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/cli.mjs +4 -4
- package/dist/index.mjs +2 -2
- package/dist/telegram.mjs +3 -3
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -864,7 +864,7 @@ ${LS}
|
|
|
864
864
|
`):" (no path captured)";return`Denial circuit breaker: this forked sub-agent hit ${t} 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:
|
|
865
865
|
${n}
|
|
866
866
|
|
|
867
|
-
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 aa,yI,s8,Im=x(()=>{"use strict";aa="denial-breaker",yI=new Set(["read_file","list_directory","glob","grep"]),s8="Sub-agent path access denied:"});import{createHash as a8}from"node:crypto";function vI(){return{recent:[],firedFingerprints:new Set}}function kI(e){let t;try{t=c8(e.input)}catch{t=String(e.input)}return a8("sha256").update(e.name).update("\0").update(t).digest("hex")}function c8(e){return JSON.stringify(HS(e))??"null"}function HS(e){if(Array.isArray(e))return e.map(HS);if(e!==null&&typeof e=="object"){let t=e,n={};for(let r of Object.keys(t).sort())n[r]=HS(t[r]);return n}return e}function d8(e,t){let n=0;for(let r of e)r===t&&(n+=1);return n}function TI(e,t){e.recent.push(t),e.recent.length>WS&&e.recent.shift();let n=d8(e.recent,t);return n>=l8&&!e.firedFingerprints.has(t)?(e.firedFingerprints.add(t),{fired:!0,count:n}):{fired:!1,count:n}}var l8,WS,EI=x(()=>{"use strict";l8=5,WS=20});var la,p8,m8,Yt,Kc=x(()=>{"use strict";be();Be();ym();um();hm();DS();yi();vm();Ie();jS();hI();Im();EI();jS();la=8,p8=new Set,m8=8,Yt=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(t){this.handlers=t.handlers,this.schemas=t.schemas,this.hookRegistry=t.hookRegistry,this.permissions=t.permissions,this.canUseTool=t.canUseTool,this.subagentExecutor=t.subagentExecutor,this.skillExecutor=t.skillExecutor,this.composeExecutor=t.composeExecutor,this.classifier=t.concurrencyClassifier??US,this.maxConcurrentSafeCalls=typeof t.maxConcurrentSafeCalls=="number"&&Number.isFinite(t.maxConcurrentSafeCalls)&&t.maxConcurrentSafeCalls>=1?Math.floor(t.maxConcurrentSafeCalls):m8,this.resolveBase=t.cwd,this._env=t.env,this.sessionId=t.sessionId,this.parentSessionId=t.parentSessionId,this.subagentId=t.subagentId,this.sessionGrantManager=t.sessionGrantManager,this.traceWriter=t.traceWriter,this.readOnlyBash=t.readOnlyBash===!0,this.maxOutputBytes=typeof t.maxOutputBytes=="number"&&Number.isFinite(t.maxOutputBytes)&&t.maxOutputBytes>0?t.maxOutputBytes:void 0,this._allowAll=t.allowAll===!0;let n=t.cwd?[t.cwd]:[];this._readRoots=t.readRoots??n.slice(),this._writeRoots=t.writeRoots??n.slice(),this.grantManager=new fo({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(t){return{...this.handlerContext,toolUseId:t.id,...this.traceWriter!==void 0?{traceWriter:this.traceWriter}:{}}}addReadRoot(t,n="slash"){this.grantManager.addReadRoot(t,n)}addWriteRoot(t,n="slash"){this.grantManager.addWriteRoot(t,n)}revokeRoot(t,n="slash"){this.grantManager.revokeRoot(t,n)}getGrants(){return this.grantManager.getGrants()}setAllowAll(t){this._allowAll=t}setResolveBase(t){let n=this.resolveBase;if(n!==t){if(this.resolveBase=t,n!==void 0){let r=this._readRoots.indexOf(n);r!==-1?this._readRoots[r]=t:this._readRoots.includes(t)||this._readRoots.push(t);let o=this._writeRoots.indexOf(n);o!==-1?this._writeRoots[o]=t:this._writeRoots.includes(t)||this._writeRoots.push(t)}else this._readRoots.includes(t)||this._readRoots.push(t),this._writeRoots.includes(t)||this._writeRoots.push(t);this.subagentExecutor?.setCwd(t),this.skillExecutor?.setCwd(t),this.composeExecutor?.setCwd(t)}}get toolDefs(){let t=this.permissions?.allowedTools;if(!t)return this.schemas;let n=new Set(t);return this.schemas.filter(r=>n.has(r.name))}async checkReadOnlyBash(t){if(!this.readOnlyBash||t.name!=="bash")return null;let n=t.input,r=typeof n=="object"&&n!==null?n.command:void 0;if(typeof r!="string")return null;let o=wm(r);if(!o.mutating)return null;let i=`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(t.name,i),{content:i,isError:!0,failureClass:"permission-denied"}}async emitPreToolUseBlock(t,n){await Rn(this.traceWriter,{hookEvent:"PreToolUse",decision:"block",blockedTool:t,reason:n,...this.subagentId!==void 0?{subagentId:this.subagentId}:{}})}checkRepeatCircuitBreaker(t){if(p8.has(t.name))return null;let n=gI(t);return this.repeatBreaker!==null&&this.repeatBreaker.fingerprint===n?this.repeatBreaker.count+=1:this.repeatBreaker={fingerprint:n,count:1},this.repeatBreaker.count<la?null:{content:`Loop circuit breaker: "${t.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(t){if(this.parentSessionId===void 0)return;this.suspectedLoopWindow===null&&(this.suspectedLoopWindow=vI());let n=kI(t),r=TI(this.suspectedLoopWindow,n);r.fired&&ie(this.traceWriter,{phase:"suspected_loop",metadata:{tool:t.name,count:r.count,windowSize:WS}})}recordForkReadDenial(t,n,r){if(this.parentSessionId===void 0||!yI.has(t.name)||!bI(n))return r;let o=this.denialBreaker??{count:0,deniedPaths:[]};o.count+=1;let i=wI(t);return o.deniedPaths.includes(i)||o.deniedPaths.push(i),this.denialBreaker=o,o.count<5?r:{content:SI(o.deniedPaths,o.count),isError:!0,failureClass:aa}}resetDenialBreaker(){this.denialBreaker=null}async runCanUseTool(t){if(!this.canUseTool)return null;let n;try{n=await this.canUseTool(t.name,t.input??{},{signal:t.signal,toolUseID:t.id})}catch(r){let o=`Tool "${t.name}" denied by canUseTool (threw): ${r instanceof Error?r.message:String(r)}`;return await this.emitPreToolUseBlock(t.name,o),{content:o,isError:!0,failureClass:"permission-denied"}}if(n.behavior==="deny"){let r=n.message||`Tool "${t.name}" denied by permission policy`;return await this.emitPreToolUseBlock(t.name,r),{content:r,isError:!0,failureClass:"permission-denied"}}return n.updatedInput!==void 0&&(t.input=n.updatedInput),null}async execute(t){if(t.signal.aborted)return{content:"Tool call aborted",isError:!0,failureClass:"abort"};if(this.hookRegistry){let a={event:"PreToolUse",toolName:t.name,input:t.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 CS(this.hookRegistry,a,{signal:t.signal,...this.traceWriter?{traceWriter:this.traceWriter}:{}})}catch(l){if(l instanceof ve)return this.recordForkReadDenial(t,l.reason,{content:`Tool "${t.name}" blocked by PreToolUse hook: ${l.message}`,isError:!0,failureClass:"hook-block"});throw l}}let n=OS(t.name,this.permissions);if(!n.allowed){let a=n.reason??`Tool "${t.name}" is not permitted`;return await this.emitPreToolUseBlock(t.name,a),{content:a,isError:!0,failureClass:"permission-denied"}}let r=await this.runCanUseTool(t);if(r)return r;let o=await this.checkReadOnlyBash(t);if(o)return o;let i=this.checkRepeatCircuitBreaker(t);if(i)return i;this.observeSuspectedLoop(t);let s=await this.executeCore(t);return s.isError!==!0&&this.resetDenialBreaker(),s}async executeBatch(t){if(t.length===0)return[];if(t.length===1)return[await this.execute(t[0])];let n=new Array(t.length),r=new Set;for(let s=0;s<t.length;s++){let a=t[s];if(a.signal.aborted){n[s]={content:"Tool call aborted",isError:!0,failureClass:"abort"},r.add(s);continue}if(this.hookRegistry){let m={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 CS(this.hookRegistry,m,{signal:a.signal,...this.traceWriter?{traceWriter:this.traceWriter}:{}})}catch(f){if(f instanceof ve){n[s]=this.recordForkReadDenial(a,f.reason,{content:`Tool "${a.name}" blocked by PreToolUse hook: ${f.message}`,isError:!0,failureClass:"hook-block"}),r.add(s);continue}throw f}}let l=OS(a.name,this.permissions);if(!l.allowed){let m=l.reason??`Tool "${a.name}" is not permitted`;await this.emitPreToolUseBlock(a.name,m),n[s]={content:m,isError:!0,failureClass:"permission-denied"},r.add(s);continue}let c=await this.runCanUseTool(a);if(c){n[s]=c,r.add(s);continue}let d=await this.checkReadOnlyBash(a);if(d){n[s]=d,r.add(s);continue}let u=this.checkRepeatCircuitBreaker(a);if(u){n[s]=u,r.add(s);continue}this.observeSuspectedLoop(a)}let o=t.map((s,a)=>({call:s,originalIndex:a})).filter((s,a)=>!r.has(a));if(o.length===0)return n;let i=fI(o.map(s=>s.call),this.classifier);for(let s of i){if(s.isConcurrencySafe){let l=await ia(s.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=s.indices[l.indexOf(c)];n[o[u].originalIndex]={content:`Tool execution error: ${d}`,isError:!0}}}else for(let l of s.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=s.indices.length;s.indices.forEach((l,c)=>{let d=n[o[l].originalIndex];d&&(d.batchIndex=c+1,d.batchSize=a)})}return n.some(s=>s!==void 0&&s.isError!==!0)&&this.resetDenialBreaker(),n}async executeCore(t){let n=await this.executeCoreInner(t);return this.applyOutputCap(n)}applyOutputCap(t){let n=this.maxOutputBytes;if(n===void 0)return t;let r=Buffer.byteLength(t.content,"utf8");return r<=n||(t.content=Cr(t.content,n),t.truncated=!0,W(`[output-cap #661] fork tool result capped: original=${r}B capped=${Buffer.byteLength(t.content,"utf8")}B (cap=${n}B)`)),t}async executeCoreInner(t){if(t.name==="agent"){if(!this.subagentExecutor)return{content:"Agent tool is not available in this session configuration",isError:!0};let s,a=!1,l="";try{s=await this.subagentExecutor.execute(t)}catch(c){a=!0,l=c instanceof Error?c.message:String(c),s={content:`Agent tool error: ${l}`,isError:!0}}return a?this.firePostToolUseFailure(t.name,l,t.signal,t.input):this.firePostToolUse(t.name,s.content,t.signal,t.input,s),s}if(t.name==="skill"){if(!this.skillExecutor)return{content:"Skill tool is not available in this session configuration",isError:!0};let s,a=!1,l="";try{s=await this.skillExecutor.execute(t)}catch(c){a=!0,l=c instanceof Error?c.message:String(c),s={content:`Skill tool error: ${l}`,isError:!0}}return a?this.firePostToolUseFailure(t.name,l,t.signal,t.input):this.firePostToolUse(t.name,s.content,t.signal,t.input,s),s}if(t.name==="compose"){let s=await this.executeCompose(t);return this.firePostToolUse(t.name,s.content,t.signal,t.input,s),s}let n=this.handlers.get(t.name);if(!n)return{content:`Unknown tool "${t.name}". Available tools: ${[...this.handlers.keys()].join(", ")}`,isError:!0};let r,o=!1,i="";try{r=await n(t.input,t.signal,this.callHandlerContext(t))}catch(s){o=!0,i=s instanceof Error?s.message:String(s),r={content:`Tool execution error: ${i}`,isError:!0}}return o?this.firePostToolUseFailure(t.name,i,t.signal,t.input):this.firePostToolUse(t.name,r.content,t.signal,t.input,r),r}async executeCompose(t){if(!this.composeExecutor)return{content:"Compose tool is not available in this session configuration",isError:!0};try{return await this.composeExecutor.execute(t)}catch(n){return{content:`Compose tool error: ${n instanceof Error?n.message:String(n)}`,isError:!0}}}firePostToolUse(t,n,r,o,i){if(!this.hookRegistry)return;let s={event:"PostToolUse",toolName:t,output:n,...o!==void 0?{input:o}:{},...this.parentSessionId!==void 0?{parentSessionId:this.parentSessionId}:{},...this.sessionGrantManager!==void 0?{grantManager:this.sessionGrantManager}:{},...i?.incomplete===!0?{incomplete:!0}:{},...i?.incompleteReason?{incompleteReason:i.incompleteReason}:{}};N_(this.hookRegistry,s,{signal:r,...this.traceWriter?{traceWriter:this.traceWriter}:{}}).catch(()=>{})}firePostToolUseFailure(t,n,r,o){if(!this.hookRegistry)return;let i={event:"PostToolUseFailure",toolName:t,error:n,...o!==void 0?{input:o}:{},...this.parentSessionId!==void 0?{parentSessionId:this.parentSessionId}:{}};B_(this.hookRegistry,i,{signal:r,...this.traceWriter?{traceWriter:this.traceWriter}:{}}).catch(s=>{W(`firePostToolUseFailure outer catch (tool=${t}): ${String(s)}`)})}}});function E8(e){let t=e.match(f8);if(!t)return null;let n=parseInt(t[1]??"0",10),r=parseInt(t[2]??"0",10),o=t[3]!==void 0?parseInt(t[3],10):void 0;return{runner:"vitest",passed:n,failed:r,...o!==void 0?{skipped:o}:{}}}function x8(e){let t=e.match(g8);if(!t)return null;let n=parseInt(t[1]??"0",10);return{runner:"jest",passed:parseInt(t[2]??"0",10),failed:n}}function R8(e){let t=e.match(h8);if(!t)return null;if(t[2]!==void 0){let n=parseInt(t[2],10),r=parseInt(t[1]??"0",10);return{runner:"pytest",passed:n,failed:r}}return t[4]!==void 0?{runner:"pytest",passed:parseInt(t[4],10),failed:0}:null}function A8(e){let t=e.match(y8);if(!t)return null;let n=parseInt(t[1]??"0",10),r=e.match(b8),o=r?parseInt(r[1]??"0",10):0;return{runner:"mocha",passed:n,failed:o}}function C8(e){let t=[...e.matchAll(w8)];if(t.length===0)return null;let n=0,r=0;for(let o of t)o[1]==="ok"?n++:o[1]==="FAIL"&&r++;return{runner:"go-test",passed:n,failed:r}}function _8(e){let t=e.match(S8);if(!t)return null;let n=parseInt(t[1]??"0",10),r=parseInt(t[2]??"0",10),o=t[3]!==void 0?parseInt(t[3],10):void 0;return{runner:"cargo",passed:n,failed:r,...o!==void 0?{skipped:o}:{}}}function I8(e){let t=e.match(v8);if(!t)return null;let n=parseInt(t[1]??"0",10),r=parseInt(t[2]??"0",10);return{runner:"rspec",passed:n-r,failed:r}}function P8(e){let t=e.match(k8);if(t)return{runner:"phpunit",passed:parseInt(t[1]??"0",10),failed:0};let n=e.match(T8);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 KS(e){return E8(e)??x8(e)??R8(e)??A8(e)??C8(e)??_8(e)??I8(e)??P8(e)??null}var f8,g8,h8,y8,b8,w8,S8,v8,k8,T8,xI=x(()=>{"use strict";f8=/Tests\s+(\d+)\s+passed(?:\s*\|\s*(\d+)\s+failed)?(?:\s*\|\s*(\d+)\s+skipped)?/,g8=/Tests:\s+(?:(\d+)\s+failed,\s*)?(\d+)\s+passed,\s*\d+\s+total/,h8=/={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,}/,y8=/(\d+)\s+passing/,b8=/(\d+)\s+failing/,w8=/^(ok|FAIL)\s+\S+\s+[\d.]+s/gm,S8=/test result: (?:ok|FAILED)\. (\d+) passed; (\d+) failed(?:; (\d+) ignored)?/,v8=/(\d+) examples?, (\d+) failures?/,k8=/OK \((\d+) tests?/,T8=/Tests:\s*(\d+)[^]*?Failures:\s*(\d+)/});function Ir(e){return e.replace(RI,"").replace(M8," ").trim()}function nr(e){return e.replace(RI,"")}var RI,M8,ho=x(()=>{"use strict";RI=/\x1B\][^\x07\x1B]*(?:\x07|\x1B\\)|\x1B[P^_X][^\x1B]*\x1B\\|\x1B\[[0-?]*[ -/]*[@-~]|\x9B[0-?]*[ -/]*[@-~]|\x1B[@-_]/g,M8=/[\x00-\x1F\x7F-\x9F]/g});import{statSync as O8}from"node:fs";function Gc(e){if(typeof e!="object"||e===null)return!1;let t=e;return t.code==="ENOENT"&&typeof t.syscall=="string"&&t.syscall.startsWith("spawn")}function $8(e){if(e===void 0)return!1;try{return O8(e),!1}catch{return!0}}function ca(e,t){let n=e instanceof Error?e.message:typeof e?.message=="string"?String(e.message):String(e);return Gc(e)&&$8(t)?`working directory does not exist: ${t} (deleted worktree?) \u2014 underlying: ${n}`:n}var GS=x(()=>{"use strict"});function rr(e){if(AI)return;AI=!0;let t=e instanceof Error?e.message:String(e);console.warn(`[afk-home] Malformed AFK home/state env var ignored while deriving the credential floor: ${t}. The relocated tree is NOT protected \u2014 the default ~/.afk entries still apply. Fix the env var to restore coverage.`)}var AI,qc=x(()=>{"use strict";AI=!1});import{realpathSync as CI}from"fs";import{dirname as D8,resolve as vi,join as qS}from"path";import{homedir as yo}from"os";function L8(){let e=[];try{let t=he();e.push(Xe(vi(qS(t,"config")))),e.push(Xe(vi(qS(t,"state"))))}catch(t){rr(t)}try{e.push(Xe(vi(me())))}catch(t){rr(t)}return e}function zS(){let e=v.AFK_WRITE_DENYLIST,t=e?e.split(":").map(r=>Xe(vi(r))).filter(Boolean):[];return[...[...new Set([...F8.map(r=>Xe(vi(r))),...L8()])],...t]}function Xe(e){let t=vi(e);try{return CI(t)}catch{}let n=[],r=t;for(let o=0;o<64;o++){let i=D8(r);if(i===r)break;n.unshift(r.slice(i.length+1)),r=i;try{let s=CI(r);return qS(s,...n)}catch{}}return t}function Pm(e,t="write_file"){let n=Xe(vi(e));for(let r of zS())if(n===r||n.startsWith(r+"/"))throw new Error(`${t}: refusing to write to protected path: ${n} (matches denylist entry: ${r})`)}var F8,da=x(()=>{"use strict";G();z();qc();F8=[`${yo()}/.ssh`,`${yo()}/.aws`,`${yo()}/.gnupg`,`${yo()}/.config/gcloud`,"/etc","/System","/private/etc","/usr/local/etc",`${yo()}/.afk/config`,`${yo()}/.afk/state`,`${yo()}/.npmrc`,`${yo()}/.docker/config.json`]});import{basename as N8,dirname as B8,join as Mm,relative as U8,resolve as ua,sep as _I}from"path";import{homedir as Qe}from"os";function PI(e){let t=ua(e);return Mm(Xe(B8(t)),N8(t))}function YS(e){return e?e.split(":").map(t=>t.trim()).filter(Boolean).map(t=>t==="~"||t.startsWith("~/")?Mm(Qe(),t.slice(1)):t).map(t=>ua(t)):[]}function H8(){try{return[Xe(ua(Mm(he(),"config")))]}catch(e){return rr(e),[]}}function W8(){try{let e=he();return bo.filter(t=>t.startsWith(II)).map(t=>PI(Mm(e,t.slice(II.length))))}catch(e){return rr(e),[]}}function MI(){let e=`${v.AFK_READ_DENYLIST??""}\0${v.AFK_HOME??""}`;if(zc&&zc.key===e)return zc;let t=YS(v.AFK_READ_DENYLIST).map(r=>Xe(r)).filter(Boolean),n=[...new Set([...JS.map(r=>Xe(ua(r))),...H8()])];return zc={key:e,builtins:n,extras:t,allow:[...new Set([...j8.map(PI),...W8()])]},zc}function VS(){let{builtins:e,extras:t}=MI();return[...e,...t]}function OI(e){let t=Xe(ua(e));return VS().map(r=>U8(t,r)).filter(r=>r!==""&&r!==".."&&!r.startsWith(`..${_I}`)).map(r=>r.split(_I).join("/"))}function Bt(e){let t=Xe(ua(e)),{builtins:n,extras:r,allow:o}=MI();for(let i of r)if(t===i||t.startsWith(i+"/"))return{denied:!0,matched:i};if(o.includes(t))return{denied:!1};for(let i of n)if(t===i||t.startsWith(i+"/"))return{denied:!0,matched:i};return{denied:!1}}var JS,bo,j8,zc,II,Pr=x(()=>{"use strict";G();da();z();qc();JS=[`${Qe()}/.ssh`,`${Qe()}/.aws`,`${Qe()}/.gnupg`,`${Qe()}/.config/gcloud`,`${Qe()}/.afk/config`,`${Qe()}/.npmrc`,`${Qe()}/.docker/config.json`,`${Qe()}/.git-credentials`,`${Qe()}/.netrc`,`${Qe()}/.config/gh/hosts.yml`,`${Qe()}/.kube/config`,"/etc/shadow","/etc/sudoers","/private/etc/master.passwd",`${Qe()}/.password-store`,`${Qe()}/Library/Application Support/Google/Chrome`,`${Qe()}/Library/Application Support/Chromium`,`${Qe()}/Library/Application Support/BraveSoftware`,`${Qe()}/Library/Application Support/Microsoft Edge`,`${Qe()}/Library/Application Support/Arc`,`${Qe()}/Library/Application Support/Firefox`],bo=[".afk/config/mcp.json"],j8=bo.map(e=>`${Qe()}/${e}`);II=".afk/"});import ki from"path";import{realpathSync as K8}from"fs";function dn(e){try{return K8.native(e)}catch{let t=ki.dirname(e),n=ki.basename(e);return t===e?e:ki.join(dn(t),n)}}function G8(e){let t=$I.get(e);if(t!==void 0)return t;let n=dn(e);return $I.set(e,n),n}function DI(e,t,n,r){let o=t?.resolveBase??t?.cwd??r,i=ki.isAbsolute(e)?e:ki.resolve(o??process.cwd(),e);if(t?.allowAll===!0)return{restricted:!1,resolved:i,roots:[]};if(o===void 0)return{restricted:!1,resolved:i,roots:[]};let s=dn(i),a=n==="read"?t?.readRoots??[o]:t?.writeRoots??[o];for(let l of a){let c=G8(l),d=ki.relative(c,s);if(!d.startsWith("..")&&!ki.isAbsolute(d))return{restricted:!1,resolved:i,roots:a}}return{restricted:!0,resolved:i,roots:a}}function un(e,t,n="read",r){let{restricted:o,resolved:i,roots:s}=DI(e,t,n,r);if(n==="read"){let a=Bt(i);if(a.denied)throw new Error(`Path \`${e}\` is a protected credential/secret path (read-denylist entry: \`${a.matched}\`) and cannot be read.`)}if(o){let a=s.map(c=>`\`${c}\``).join(", "),l=n==="read"?"read roots":"write roots";throw new Error(`Path \`${e}\` is outside the allowed ${l} [${a}].`)}return i}function Jc(e,t,n="read",r){return DI(e,t,n,r)}function FI(e){let t=new Set,n=[];for(let r of e.split(/\s+/)){if(r.length===0)continue;let o=r.replace(/^\d*[<>|&]+/,"").replace(/^['"]/,"").replace(/['";,)]+$/,"");if(o.length===0)continue;let i=o.startsWith("/"),s=o==="~"||o.startsWith("~/");!i&&!s||t.has(o)||(t.add(o),n.push(o))}return n}var $I,In=x(()=>{"use strict";Pr();$I=new Map});import{spawn as q8}from"child_process";import z8 from"os";function J8(e){if(typeof e!="object"||e===null)throw new Error("Input must be an object");let t=e;if(typeof t.command!="string")throw new Error('Input must have a "command" field of type string');let n=12e4;if(t.timeout_ms!==void 0){if(typeof t.timeout_ms!="number")throw new Error("timeout_ms must be a number");if(t.timeout_ms<0||t.timeout_ms>6e5)throw new Error("timeout_ms must be between 0 and 600000");n=t.timeout_ms}return{command:t.command,timeout_ms:n}}function Om(e,t){let n=!1,r=!1;function o(){n||e==="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 i(s,a){if(r)return;let l=a.resolveBase??a.cwd??t,c=z8.homedir(),d=[];for(let u of FI(s)){let m=u==="~"?c:u.startsWith("~/")?c+u.slice(1):u,f=Jc(m,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(s,a,l)=>{let{command:c,timeout_ms:d}=J8(s);if(a.aborted)return{content:"Command aborted",isError:!0};if(o(),l!==void 0)try{i(c,l)}catch{}return new Promise(u=>{let m=!1;function f(A){m||(m=!0,clearTimeout(h),a.removeEventListener("abort",T),u(A))}let g=q8(c,{shell:!0,detached:!0,stdio:["ignore","pipe","pipe"],...(l?.resolveBase??l?.cwd??t)!==void 0?{cwd:l?.resolveBase??l?.cwd??t}:{},...l?.env!==void 0?{env:{...process.env,...l.env}}:{}});g.unref();let h=setTimeout(()=>{g.pid!==void 0&&process.kill(-g.pid,"SIGKILL"),f({content:`Command timed out after ${d}ms`,isError:!0})},d),y="",b="",w=0,S=!1;function k(A){if(S||m||w<8e6)return;S=!0,console.warn(`[bash] overflow kill: stream=${A} totalBytes=${w} command="${c}"`),Le({event:"tool.overflow_kill",tool:"bash",total_bytes:w,stream:A}),g.kill("SIGKILL");let O=nr((y+b).trimEnd()),E=KS(O)??void 0,D=Cr(O,1e5)+Sm;f({content:D,truncated:!0,...E!==void 0?{testResult:E}:{}})}g.stdout.on("data",A=>{let O=8e6-w,E=A.length<=O?A:A.subarray(0,Math.max(0,O));w+=E.length,y+=E.toString("utf8"),k("stdout")}),g.stderr.on("data",A=>{let O=8e6-w,E=A.length<=O?A:A.subarray(0,Math.max(0,O));w+=E.length,b+=E.toString("utf8"),k("stderr")});let T=()=>{g.pid!==void 0&&process.kill(-g.pid,"SIGKILL"),f({content:"Command aborted",isError:!0})};a.addEventListener("abort",T),a.aborted&&T(),g.on("close",A=>{if(a.aborted){f({content:"Command aborted",isError:!0});return}if(A!==null&&A!==0){let C=mo(b.trimEnd()||y.trimEnd());f({content:`Command exited with code ${A}${C.content?`
|
|
867
|
+
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 aa,yI,s8,Im=x(()=>{"use strict";aa="denial-breaker",yI=new Set(["read_file","list_directory","glob","grep"]),s8="Sub-agent path access denied:"});import{createHash as a8}from"node:crypto";function vI(){return{recent:[],firedFingerprints:new Set}}function kI(e){let t;try{t=c8(e.input)}catch{t=String(e.input)}return a8("sha256").update(e.name).update("\0").update(t).digest("hex")}function c8(e){return JSON.stringify(HS(e))??"null"}function HS(e){if(Array.isArray(e))return e.map(HS);if(e!==null&&typeof e=="object"){let t=e,n={};for(let r of Object.keys(t).sort())n[r]=HS(t[r]);return n}return e}function d8(e,t){let n=0;for(let r of e)r===t&&(n+=1);return n}function TI(e,t){e.recent.push(t),e.recent.length>WS&&e.recent.shift();let n=d8(e.recent,t);return n>=l8&&!e.firedFingerprints.has(t)?(e.firedFingerprints.add(t),{fired:!0,count:n}):{fired:!1,count:n}}var l8,WS,EI=x(()=>{"use strict";l8=5,WS=20});var la,p8,m8,Yt,Kc=x(()=>{"use strict";be();Be();ym();um();hm();DS();yi();vm();Ie();jS();hI();Im();EI();jS();la=8,p8=new Set,m8=8,Yt=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(t){this.handlers=t.handlers,this.schemas=t.schemas,this.hookRegistry=t.hookRegistry,this.permissions=t.permissions,this.canUseTool=t.canUseTool,this.subagentExecutor=t.subagentExecutor,this.skillExecutor=t.skillExecutor,this.composeExecutor=t.composeExecutor,this.classifier=t.concurrencyClassifier??US,this.maxConcurrentSafeCalls=typeof t.maxConcurrentSafeCalls=="number"&&Number.isFinite(t.maxConcurrentSafeCalls)&&t.maxConcurrentSafeCalls>=1?Math.floor(t.maxConcurrentSafeCalls):m8,this.resolveBase=t.cwd,this._env=t.env,this.sessionId=t.sessionId,this.parentSessionId=t.parentSessionId,this.subagentId=t.subagentId,this.sessionGrantManager=t.sessionGrantManager,this.traceWriter=t.traceWriter,this.readOnlyBash=t.readOnlyBash===!0,this.maxOutputBytes=typeof t.maxOutputBytes=="number"&&Number.isFinite(t.maxOutputBytes)&&t.maxOutputBytes>0?t.maxOutputBytes:void 0,this._allowAll=t.allowAll===!0;let n=t.cwd?[t.cwd]:[];this._readRoots=t.readRoots??n.slice(),this._writeRoots=t.writeRoots??n.slice(),this.grantManager=new fo({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(t){return{...this.handlerContext,toolUseId:t.id,...this.traceWriter!==void 0?{traceWriter:this.traceWriter}:{}}}addReadRoot(t,n="slash"){this.grantManager.addReadRoot(t,n)}addWriteRoot(t,n="slash"){this.grantManager.addWriteRoot(t,n)}revokeRoot(t,n="slash"){this.grantManager.revokeRoot(t,n)}getGrants(){return this.grantManager.getGrants()}setAllowAll(t){this._allowAll=t}setResolveBase(t){let n=this.resolveBase;if(n!==t){if(this.resolveBase=t,n!==void 0){let r=this._readRoots.indexOf(n);r!==-1?this._readRoots[r]=t:this._readRoots.includes(t)||this._readRoots.push(t);let o=this._writeRoots.indexOf(n);o!==-1?this._writeRoots[o]=t:this._writeRoots.includes(t)||this._writeRoots.push(t)}else this._readRoots.includes(t)||this._readRoots.push(t),this._writeRoots.includes(t)||this._writeRoots.push(t);this.subagentExecutor?.setCwd(t),this.skillExecutor?.setCwd(t),this.composeExecutor?.setCwd(t)}}get toolDefs(){let t=this.permissions?.allowedTools;if(!t)return this.schemas;let n=new Set(t);return this.schemas.filter(r=>n.has(r.name))}async checkReadOnlyBash(t){if(!this.readOnlyBash||t.name!=="bash")return null;let n=t.input,r=typeof n=="object"&&n!==null?n.command:void 0;if(typeof r!="string")return null;let o=wm(r);if(!o.mutating)return null;let i=`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(t.name,i),{content:i,isError:!0,failureClass:"permission-denied"}}async emitPreToolUseBlock(t,n){await Rn(this.traceWriter,{hookEvent:"PreToolUse",decision:"block",blockedTool:t,reason:n,...this.subagentId!==void 0?{subagentId:this.subagentId}:{}})}checkRepeatCircuitBreaker(t){if(p8.has(t.name))return null;let n=gI(t);return this.repeatBreaker!==null&&this.repeatBreaker.fingerprint===n?this.repeatBreaker.count+=1:this.repeatBreaker={fingerprint:n,count:1},this.repeatBreaker.count<la?null:{content:`Loop circuit breaker: "${t.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(t){if(this.parentSessionId===void 0)return;this.suspectedLoopWindow===null&&(this.suspectedLoopWindow=vI());let n=kI(t),r=TI(this.suspectedLoopWindow,n);r.fired&&ie(this.traceWriter,{phase:"suspected_loop",metadata:{tool:t.name,count:r.count,windowSize:WS}})}recordForkReadDenial(t,n,r){if(this.parentSessionId===void 0||!yI.has(t.name)||!bI(n))return r;let o=this.denialBreaker??{count:0,deniedPaths:[]};o.count+=1;let i=wI(t);return o.deniedPaths.includes(i)||o.deniedPaths.push(i),this.denialBreaker=o,o.count<5?r:{content:SI(o.deniedPaths,o.count),isError:!0,failureClass:aa}}resetDenialBreaker(){this.denialBreaker=null}async runCanUseTool(t){if(!this.canUseTool)return null;let n;try{n=await this.canUseTool(t.name,t.input??{},{signal:t.signal,toolUseID:t.id})}catch(r){let o=`Tool "${t.name}" denied by canUseTool (threw): ${r instanceof Error?r.message:String(r)}`;return await this.emitPreToolUseBlock(t.name,o),{content:o,isError:!0,failureClass:"permission-denied"}}if(n.behavior==="deny"){let r=n.message||`Tool "${t.name}" denied by permission policy`;return await this.emitPreToolUseBlock(t.name,r),{content:r,isError:!0,failureClass:"permission-denied"}}return n.updatedInput!==void 0&&(t.input=n.updatedInput),null}async execute(t){if(t.signal.aborted)return{content:"Tool call aborted",isError:!0,failureClass:"abort"};if(this.hookRegistry){let a={event:"PreToolUse",toolName:t.name,input:t.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 CS(this.hookRegistry,a,{signal:t.signal,...this.traceWriter?{traceWriter:this.traceWriter}:{}})}catch(l){if(l instanceof ve)return this.recordForkReadDenial(t,l.reason,{content:`Tool "${t.name}" blocked by PreToolUse hook: ${l.message}`,isError:!0,failureClass:"hook-block"});throw l}}let n=OS(t.name,this.permissions);if(!n.allowed){let a=n.reason??`Tool "${t.name}" is not permitted`;return await this.emitPreToolUseBlock(t.name,a),{content:a,isError:!0,failureClass:"permission-denied"}}let r=await this.runCanUseTool(t);if(r)return r;let o=await this.checkReadOnlyBash(t);if(o)return o;let i=this.checkRepeatCircuitBreaker(t);if(i)return i;this.observeSuspectedLoop(t);let s=await this.executeCore(t);return s.isError!==!0&&this.resetDenialBreaker(),s}async executeBatch(t){if(t.length===0)return[];if(t.length===1)return[await this.execute(t[0])];let n=new Array(t.length),r=new Set;for(let s=0;s<t.length;s++){let a=t[s];if(a.signal.aborted){n[s]={content:"Tool call aborted",isError:!0,failureClass:"abort"},r.add(s);continue}if(this.hookRegistry){let m={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 CS(this.hookRegistry,m,{signal:a.signal,...this.traceWriter?{traceWriter:this.traceWriter}:{}})}catch(f){if(f instanceof ve){n[s]=this.recordForkReadDenial(a,f.reason,{content:`Tool "${a.name}" blocked by PreToolUse hook: ${f.message}`,isError:!0,failureClass:"hook-block"}),r.add(s);continue}throw f}}let l=OS(a.name,this.permissions);if(!l.allowed){let m=l.reason??`Tool "${a.name}" is not permitted`;await this.emitPreToolUseBlock(a.name,m),n[s]={content:m,isError:!0,failureClass:"permission-denied"},r.add(s);continue}let c=await this.runCanUseTool(a);if(c){n[s]=c,r.add(s);continue}let d=await this.checkReadOnlyBash(a);if(d){n[s]=d,r.add(s);continue}let u=this.checkRepeatCircuitBreaker(a);if(u){n[s]=u,r.add(s);continue}this.observeSuspectedLoop(a)}let o=t.map((s,a)=>({call:s,originalIndex:a})).filter((s,a)=>!r.has(a));if(o.length===0)return n;let i=fI(o.map(s=>s.call),this.classifier);for(let s of i){if(s.isConcurrencySafe){let l=await ia(s.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=s.indices[l.indexOf(c)];n[o[u].originalIndex]={content:`Tool execution error: ${d}`,isError:!0}}}else for(let l of s.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=s.indices.length;s.indices.forEach((l,c)=>{let d=n[o[l].originalIndex];d&&(d.batchIndex=c+1,d.batchSize=a)})}return n.some(s=>s!==void 0&&s.isError!==!0)&&this.resetDenialBreaker(),n}async executeCore(t){let n=await this.executeCoreInner(t);return this.applyOutputCap(n)}applyOutputCap(t){let n=this.maxOutputBytes;if(n===void 0)return t;let r=Buffer.byteLength(t.content,"utf8");return r<=n||(t.content=Cr(t.content,n),t.truncated=!0,W(`[output-cap #661] fork tool result capped: original=${r}B capped=${Buffer.byteLength(t.content,"utf8")}B (cap=${n}B)`)),t}async executeCoreInner(t){if(t.name==="agent"){if(!this.subagentExecutor)return{content:"Agent tool is not available in this session configuration",isError:!0};let s,a=!1,l="";try{s=await this.subagentExecutor.execute(t)}catch(c){a=!0,l=c instanceof Error?c.message:String(c),s={content:`Agent tool error: ${l}`,isError:!0}}return a?this.firePostToolUseFailure(t.name,l,t.signal,t.input):this.firePostToolUse(t.name,s.content,t.signal,t.input,s),s}if(t.name==="skill"){if(!this.skillExecutor)return{content:"Skill tool is not available in this session configuration",isError:!0};let s,a=!1,l="";try{s=await this.skillExecutor.execute(t)}catch(c){a=!0,l=c instanceof Error?c.message:String(c),s={content:`Skill tool error: ${l}`,isError:!0}}return a?this.firePostToolUseFailure(t.name,l,t.signal,t.input):this.firePostToolUse(t.name,s.content,t.signal,t.input,s),s}if(t.name==="compose"){let s=await this.executeCompose(t);return this.firePostToolUse(t.name,s.content,t.signal,t.input,s),s}let n=this.handlers.get(t.name);if(!n)return{content:`Unknown tool "${t.name}". Available tools: ${[...this.handlers.keys()].join(", ")}`,isError:!0};let r,o=!1,i="";try{r=await n(t.input,t.signal,this.callHandlerContext(t))}catch(s){o=!0,i=s instanceof Error?s.message:String(s),r={content:`Tool execution error: ${i}`,isError:!0}}return o?this.firePostToolUseFailure(t.name,i,t.signal,t.input):this.firePostToolUse(t.name,r.content,t.signal,t.input,r),r}async executeCompose(t){if(!this.composeExecutor)return{content:"Compose tool is not available in this session configuration",isError:!0};try{return await this.composeExecutor.execute(t)}catch(n){return{content:`Compose tool error: ${n instanceof Error?n.message:String(n)}`,isError:!0}}}firePostToolUse(t,n,r,o,i){if(!this.hookRegistry)return;let s={event:"PostToolUse",toolName:t,output:n,...o!==void 0?{input:o}:{},...this.parentSessionId!==void 0?{parentSessionId:this.parentSessionId}:{},...this.sessionGrantManager!==void 0?{grantManager:this.sessionGrantManager}:{},...i?.incomplete===!0?{incomplete:!0}:{},...i?.incompleteReason?{incompleteReason:i.incompleteReason}:{}};N_(this.hookRegistry,s,{signal:r,...this.traceWriter?{traceWriter:this.traceWriter}:{}}).catch(()=>{})}firePostToolUseFailure(t,n,r,o){if(!this.hookRegistry)return;let i={event:"PostToolUseFailure",toolName:t,error:n,...o!==void 0?{input:o}:{},...this.parentSessionId!==void 0?{parentSessionId:this.parentSessionId}:{}};B_(this.hookRegistry,i,{signal:r,...this.traceWriter?{traceWriter:this.traceWriter}:{}}).catch(s=>{W(`firePostToolUseFailure outer catch (tool=${t}): ${String(s)}`)})}}});function E8(e){let t=e.match(f8);if(!t)return null;let n=parseInt(t[1]??"0",10),r=parseInt(t[2]??"0",10),o=t[3]!==void 0?parseInt(t[3],10):void 0;return{runner:"vitest",passed:n,failed:r,...o!==void 0?{skipped:o}:{}}}function x8(e){let t=e.match(g8);if(!t)return null;let n=parseInt(t[1]??"0",10);return{runner:"jest",passed:parseInt(t[2]??"0",10),failed:n}}function R8(e){let t=e.match(h8);if(!t)return null;if(t[2]!==void 0){let n=parseInt(t[2],10),r=parseInt(t[1]??"0",10);return{runner:"pytest",passed:n,failed:r}}return t[4]!==void 0?{runner:"pytest",passed:parseInt(t[4],10),failed:0}:null}function A8(e){let t=e.match(y8);if(!t)return null;let n=parseInt(t[1]??"0",10),r=e.match(b8),o=r?parseInt(r[1]??"0",10):0;return{runner:"mocha",passed:n,failed:o}}function C8(e){let t=[...e.matchAll(w8)];if(t.length===0)return null;let n=0,r=0;for(let o of t)o[1]==="ok"?n++:o[1]==="FAIL"&&r++;return{runner:"go-test",passed:n,failed:r}}function _8(e){let t=e.match(S8);if(!t)return null;let n=parseInt(t[1]??"0",10),r=parseInt(t[2]??"0",10),o=t[3]!==void 0?parseInt(t[3],10):void 0;return{runner:"cargo",passed:n,failed:r,...o!==void 0?{skipped:o}:{}}}function I8(e){let t=e.match(v8);if(!t)return null;let n=parseInt(t[1]??"0",10),r=parseInt(t[2]??"0",10);return{runner:"rspec",passed:n-r,failed:r}}function P8(e){let t=e.match(k8);if(t)return{runner:"phpunit",passed:parseInt(t[1]??"0",10),failed:0};let n=e.match(T8);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 KS(e){return E8(e)??x8(e)??R8(e)??A8(e)??C8(e)??_8(e)??I8(e)??P8(e)??null}var f8,g8,h8,y8,b8,w8,S8,v8,k8,T8,xI=x(()=>{"use strict";f8=/Tests\s+(\d+)\s+passed(?:\s*\|\s*(\d+)\s+failed)?(?:\s*\|\s*(\d+)\s+skipped)?/,g8=/Tests:\s+(?:(\d+)\s+failed,\s*)?(\d+)\s+passed,\s*\d+\s+total/,h8=/={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,}/,y8=/(\d+)\s+passing/,b8=/(\d+)\s+failing/,w8=/^(ok|FAIL)\s+\S+\s+[\d.]+s/gm,S8=/test result: (?:ok|FAILED)\. (\d+) passed; (\d+) failed(?:; (\d+) ignored)?/,v8=/(\d+) examples?, (\d+) failures?/,k8=/OK \((\d+) tests?/,T8=/Tests:\s*(\d+)[^]*?Failures:\s*(\d+)/});function Ir(e){return e.replace(RI,"").replace(M8," ").trim()}function nr(e){return e.replace(RI,"")}var RI,M8,ho=x(()=>{"use strict";RI=/\x1B\][^\x07\x1B]*(?:\x07|\x1B\\)|\x1B[P^_X][^\x1B]*\x1B\\|\x1B\[[0-?]*[ -/]*[@-~]|\x9B[0-?]*[ -/]*[@-~]|\x1B[@-_]/g,M8=/[\x00-\x1F\x7F-\x9F]/g});import{statSync as O8}from"node:fs";function Gc(e){if(typeof e!="object"||e===null)return!1;let t=e;return t.code==="ENOENT"&&typeof t.syscall=="string"&&t.syscall.startsWith("spawn")}function $8(e){if(e===void 0)return!1;try{return O8(e),!1}catch{return!0}}function ca(e,t){let n=e instanceof Error?e.message:typeof e?.message=="string"?String(e.message):String(e);return Gc(e)&&$8(t)?`working directory does not exist: ${t} (deleted worktree?) \u2014 underlying: ${n}`:n}var GS=x(()=>{"use strict"});function rr(e){if(AI)return;AI=!0;let t=e instanceof Error?e.message:String(e);console.warn(`[afk-home] Malformed AFK home/state env var ignored while deriving the credential floor: ${t}. The relocated tree is NOT protected \u2014 the default ~/.afk entries still apply. Fix the env var to restore coverage.`)}var AI,qc=x(()=>{"use strict";AI=!1});import{realpathSync as CI}from"fs";import{dirname as D8,resolve as vi,join as qS}from"path";import{homedir as yo}from"os";function L8(){let e=[];try{let t=he();e.push(Xe(vi(qS(t,"config")))),e.push(Xe(vi(qS(t,"state"))))}catch(t){rr(t)}try{e.push(Xe(vi(me())))}catch(t){rr(t)}return e}function zS(){let e=v.AFK_WRITE_DENYLIST,t=e?e.split(":").map(r=>Xe(vi(r))).filter(Boolean):[];return[...[...new Set([...F8.map(r=>Xe(vi(r))),...L8()])],...t]}function Xe(e){let t=vi(e);try{return CI(t)}catch{}let n=[],r=t;for(let o=0;o<64;o++){let i=D8(r);if(i===r)break;n.unshift(r.slice(i.length+1)),r=i;try{let s=CI(r);return qS(s,...n)}catch{}}return t}function Pm(e,t="write_file"){let n=Xe(vi(e));for(let r of zS())if(n===r||n.startsWith(r+"/"))throw new Error(`${t}: refusing to write to protected path: ${n} (matches denylist entry: ${r})`)}var F8,da=x(()=>{"use strict";G();z();qc();F8=[`${yo()}/.ssh`,`${yo()}/.aws`,`${yo()}/.gnupg`,`${yo()}/.config/gcloud`,"/etc","/System","/private/etc","/usr/local/etc",`${yo()}/.afk/config`,`${yo()}/.afk/state`,`${yo()}/.npmrc`,`${yo()}/.docker/config.json`]});import{basename as N8,dirname as B8,join as Mm,relative as U8,resolve as ua,sep as _I}from"path";import{homedir as Qe}from"os";function PI(e){let t=ua(e);return Mm(Xe(B8(t)),N8(t))}function YS(e){return e?e.split(":").map(t=>t.trim()).filter(Boolean).map(t=>t==="~"||t.startsWith("~/")?Mm(Qe(),t.slice(1)):t).map(t=>ua(t)):[]}function H8(){try{return[Xe(ua(Mm(he(),"config")))]}catch(e){return rr(e),[]}}function W8(){try{let e=he();return bo.filter(t=>t.startsWith(II)).map(t=>PI(Mm(e,t.slice(II.length))))}catch(e){return rr(e),[]}}function MI(){let e=`${v.AFK_READ_DENYLIST??""}\0${v.AFK_HOME??""}`;if(zc&&zc.key===e)return zc;let t=YS(v.AFK_READ_DENYLIST).map(r=>Xe(r)).filter(Boolean),n=[...new Set([...JS.map(r=>Xe(ua(r))),...H8()])];return zc={key:e,builtins:n,extras:t,allow:[...new Set([...j8.map(PI),...W8()])]},zc}function VS(){let{builtins:e,extras:t}=MI();return[...e,...t]}function OI(e){let t=Xe(ua(e));return VS().map(r=>U8(t,r)).filter(r=>r!==""&&r!==".."&&!r.startsWith(`..${_I}`)).map(r=>r.split(_I).join("/"))}function Bt(e){let t=Xe(ua(e)),{builtins:n,extras:r,allow:o}=MI();for(let i of r)if(t===i||t.startsWith(i+"/"))return{denied:!0,matched:i};if(o.includes(t))return{denied:!1};for(let i of n)if(t===i||t.startsWith(i+"/"))return{denied:!0,matched:i};return{denied:!1}}var JS,bo,j8,zc,II,Pr=x(()=>{"use strict";G();da();z();qc();JS=[`${Qe()}/.ssh`,`${Qe()}/.aws`,`${Qe()}/.gnupg`,`${Qe()}/.config/gcloud`,`${Qe()}/.afk/config`,`${Qe()}/.npmrc`,`${Qe()}/.docker/config.json`,`${Qe()}/.git-credentials`,`${Qe()}/.netrc`,`${Qe()}/.config/gh/hosts.yml`,`${Qe()}/.kube/config`,"/etc/shadow","/etc/sudoers","/private/etc/master.passwd",`${Qe()}/.password-store`,`${Qe()}/Library/Application Support/Google/Chrome`,`${Qe()}/Library/Application Support/Chromium`,`${Qe()}/Library/Application Support/BraveSoftware`,`${Qe()}/Library/Application Support/Microsoft Edge`,`${Qe()}/Library/Application Support/Arc`,`${Qe()}/Library/Application Support/Firefox`],bo=[".afk/config/mcp.json",".ssh/config",".ssh/known_hosts"],j8=bo.map(e=>`${Qe()}/${e}`);II=".afk/"});import ki from"path";import{realpathSync as K8}from"fs";function dn(e){try{return K8.native(e)}catch{let t=ki.dirname(e),n=ki.basename(e);return t===e?e:ki.join(dn(t),n)}}function G8(e){let t=$I.get(e);if(t!==void 0)return t;let n=dn(e);return $I.set(e,n),n}function DI(e,t,n,r){let o=t?.resolveBase??t?.cwd??r,i=ki.isAbsolute(e)?e:ki.resolve(o??process.cwd(),e);if(t?.allowAll===!0)return{restricted:!1,resolved:i,roots:[]};if(o===void 0)return{restricted:!1,resolved:i,roots:[]};let s=dn(i),a=n==="read"?t?.readRoots??[o]:t?.writeRoots??[o];for(let l of a){let c=G8(l),d=ki.relative(c,s);if(!d.startsWith("..")&&!ki.isAbsolute(d))return{restricted:!1,resolved:i,roots:a}}return{restricted:!0,resolved:i,roots:a}}function un(e,t,n="read",r){let{restricted:o,resolved:i,roots:s}=DI(e,t,n,r);if(n==="read"){let a=Bt(i);if(a.denied)throw new Error(`Path \`${e}\` is a protected credential/secret path (read-denylist entry: \`${a.matched}\`) and cannot be read.`)}if(o){let a=s.map(c=>`\`${c}\``).join(", "),l=n==="read"?"read roots":"write roots";throw new Error(`Path \`${e}\` is outside the allowed ${l} [${a}].`)}return i}function Jc(e,t,n="read",r){return DI(e,t,n,r)}function FI(e){let t=new Set,n=[];for(let r of e.split(/\s+/)){if(r.length===0)continue;let o=r.replace(/^\d*[<>|&]+/,"").replace(/^['"]/,"").replace(/['";,)]+$/,"");if(o.length===0)continue;let i=o.startsWith("/"),s=o==="~"||o.startsWith("~/");!i&&!s||t.has(o)||(t.add(o),n.push(o))}return n}var $I,In=x(()=>{"use strict";Pr();$I=new Map});import{spawn as q8}from"child_process";import z8 from"os";function J8(e){if(typeof e!="object"||e===null)throw new Error("Input must be an object");let t=e;if(typeof t.command!="string")throw new Error('Input must have a "command" field of type string');let n=12e4;if(t.timeout_ms!==void 0){if(typeof t.timeout_ms!="number")throw new Error("timeout_ms must be a number");if(t.timeout_ms<0||t.timeout_ms>6e5)throw new Error("timeout_ms must be between 0 and 600000");n=t.timeout_ms}return{command:t.command,timeout_ms:n}}function Om(e,t){let n=!1,r=!1;function o(){n||e==="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 i(s,a){if(r)return;let l=a.resolveBase??a.cwd??t,c=z8.homedir(),d=[];for(let u of FI(s)){let m=u==="~"?c:u.startsWith("~/")?c+u.slice(1):u,f=Jc(m,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(s,a,l)=>{let{command:c,timeout_ms:d}=J8(s);if(a.aborted)return{content:"Command aborted",isError:!0};if(o(),l!==void 0)try{i(c,l)}catch{}return new Promise(u=>{let m=!1;function f(A){m||(m=!0,clearTimeout(h),a.removeEventListener("abort",T),u(A))}let g=q8(c,{shell:!0,detached:!0,stdio:["ignore","pipe","pipe"],...(l?.resolveBase??l?.cwd??t)!==void 0?{cwd:l?.resolveBase??l?.cwd??t}:{},...l?.env!==void 0?{env:{...process.env,...l.env}}:{}});g.unref();let h=setTimeout(()=>{g.pid!==void 0&&process.kill(-g.pid,"SIGKILL"),f({content:`Command timed out after ${d}ms`,isError:!0})},d),y="",b="",w=0,S=!1;function k(A){if(S||m||w<8e6)return;S=!0,console.warn(`[bash] overflow kill: stream=${A} totalBytes=${w} command="${c}"`),Le({event:"tool.overflow_kill",tool:"bash",total_bytes:w,stream:A}),g.kill("SIGKILL");let O=nr((y+b).trimEnd()),E=KS(O)??void 0,D=Cr(O,1e5)+Sm;f({content:D,truncated:!0,...E!==void 0?{testResult:E}:{}})}g.stdout.on("data",A=>{let O=8e6-w,E=A.length<=O?A:A.subarray(0,Math.max(0,O));w+=E.length,y+=E.toString("utf8"),k("stdout")}),g.stderr.on("data",A=>{let O=8e6-w,E=A.length<=O?A:A.subarray(0,Math.max(0,O));w+=E.length,b+=E.toString("utf8"),k("stderr")});let T=()=>{g.pid!==void 0&&process.kill(-g.pid,"SIGKILL"),f({content:"Command aborted",isError:!0})};a.addEventListener("abort",T),a.aborted&&T(),g.on("close",A=>{if(a.aborted){f({content:"Command aborted",isError:!0});return}if(A!==null&&A!==0){let C=mo(b.trimEnd()||y.trimEnd());f({content:`Command exited with code ${A}${C.content?`
|
|
868
868
|
`+C.content:""}`,isError:!0,...C.truncated?{truncated:!0}:{}});return}if(S)return;let O=nr((y+b).trimEnd()),E=KS(O)??void 0,D=mo(O);f({content:D.content,...D.truncated?{truncated:!0}:{},...E!==void 0?{testResult:E}:{}})}),g.on("error",A=>{let O=l?.resolveBase??l?.cwd??t,E;if(O===void 0&&Gc(A))try{let D=process.cwd();E=ca(A,D)}catch{E=`working directory does not exist (process cwd deleted \u2014 deleted worktree?) \u2014 underlying: ${A.message}`}else E=ca(A,O);f({content:`Failed to execute: ${E}`,isError:!0})})})}}var LI,NI=x(()=>{"use strict";tr();xI();ho();GS();yi();In();LI=Om("default")});import{promises as Y8}from"fs";function XS(e){return(t,n,r)=>V8(t,n,r,e)}var V8,BI,UI=x(()=>{"use strict";In();V8=async(e,t,n,r)=>{if(!e||typeof e!="object")return{content:"Invalid input: expected an object",isError:!0};let o=e,i=o.file_path,s=o.offset??1,a=o.limit??2e3;if(typeof i!="string")return{content:"Invalid input: file_path must be a string",isError:!0};if(typeof s!="number"||s<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=un(i,n,"read",r)}catch(c){return{content:c instanceof Error?c.message:String(c),isError:!0}}try{let c=await Y8.readFile(l),d=Math.min(8192,c.length);for(let S=0;S<d;S++)if(c[S]===0)return{content:`File appears to be binary: ${l}`,isError:!0};let u=c.toString("utf-8");if(u.length===0)return{content:""};let m=u.split(`
|
|
869
869
|
`),f=Math.max(0,s-1),g=Math.min(m.length,f+a),h=m.slice(f,g),y=m.length;if(h.length===0)return{content:`... (offset ${s} is past end of file \u2014 file has ${y} lines)`};let b=String(y).length,w=h.map((S,k)=>{let T=f+k+1;return`${String(T).padStart(b," ")} ${S}`}).join(`
|
|
870
870
|
`);if(h.length<y){let S=f+1,k=f+h.length,T=k<y?` \u2014 pass offset=${k+1} to continue`:"";return{content:`${w}
|
|
@@ -875,7 +875,7 @@ Remedy: these paths are outside the fork's granted read roots. Re-dispatch with
|
|
|
875
875
|
|
|
876
876
|
`).trim()}function x6(e){return(e?.textContent??"").replace(/\s+/g," ").trim().length}async function iP(e,t){let{JSDOM:n,Readability:r,turndown:o}=await E6(),s=new n(e,{url:t}).window.document,a=(s.title??"").trim(),l=(()=>{try{let m=s.cloneNode(!0);return new r(m).parse()}catch{return null}})();if(l&&typeof l.content=="string"&&l.content.trim().length>0){let m=oP(o.turndown(l.content)),f=(l.title??"").trim()||a,g=typeof l.length=="number"&&l.length>0?l.length:(l.textContent??"").replace(/\s+/g," ").trim().length;return{title:f,markdown:m,textLength:g,usedFallback:!1}}let c=s.body,d=c?.innerHTML??"",u=oP(o.turndown(d));return{title:a,markdown:u,textLength:x6(c),usedFallback:!0}}var ov,sP=x(()=>{"use strict";ov=null});function A6(e,t){return new Promise((n,r)=>{if(t?.aborted){r(t.reason??new Error("aborted"));return}let o=()=>{clearTimeout(i),r(t?.reason??new Error("aborted"))},i=setTimeout(()=>{t?.removeEventListener("abort",o),n()},e);t?.addEventListener("abort",o,{once:!0})})}function aP(e,t,n){let r=Math.min(t*2**e,n);return Math.round(Math.random()*r)}function C6(e,t){let n=e.headers.get("retry-after");if(n===null)return null;let r=Number(n.trim());return!Number.isFinite(r)||r<0?null:Math.min(r*1e3,t)}async function lP(e,t,n={},r={}){let o=r.retries??3,i=r.baseDelayMs??500,s=r.maxDelayMs??1e4,a=r.sleep??A6,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 e(t,n);if(!R6.has(u.status)||d===o)return u;let m=C6(u,s)??aP(d,i,s);W("[web/retryFetch] retrying",{url:t,attempt:d,status:u.status,waitMs:m}),await u.body?.cancel().catch(()=>{}),await a(m,l)}catch(u){if(l?.aborted||(c=u,d===o))throw u;let m=aP(d,i,s);W("[web/retryFetch] retrying after error",{url:t,attempt:d,waitMs:m}),await a(m,l)}}throw c??new Error("retryFetch: exhausted without a result")}var R6,cP=x(()=>{"use strict";be();R6=new Set([429,502,503,504])});import{BlockList as _6,isIP as sv}from"node:net";import{lookup as I6}from"node:dns/promises";import{Agent as P6}from"undici";function uP(){let e=v.AFK_WEB_ALLOW_PRIVATE_HOSTS?.trim().toLowerCase();return e==="1"||e==="true"}function D6(e){return e.startsWith("[")&&e.endsWith("]")?e.slice(1,-1):e}function iv(e){let t=sv(e);return t===0?!1:$6.check(e,t===4?"ipv4":"ipv6")}async function pP(e){return I6(e,{all:!0,verbatim:!0})}async function av(e,t={}){if(t.allowPrivateHosts??uP())return{allowed:!0};let n;try{n=new URL(e)}catch{return{allowed:!1,reason:`"${e}" 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=D6(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(sv(r)!==0)return iv(r)?{allowed:!1,reason:o(r,r)}:{allowed:!0};let i=t.lookupFn??pP,s;try{s=await i(r)}catch{return{allowed:!0}}for(let a of s)if(iv(a.address))return{allowed:!1,reason:o(a.address,`${r} (resolved)`)};return{allowed:!0}}async function Vc(e,t={}){let n=await av(e,t);if(!n.allowed)throw new Pn(n.reason)}async function Dm(e,t,n={},r={}){let o={...r.lookupFn!==void 0?{lookupFn:r.lookupFn}:{},...r.allowPrivateHosts!==void 0?{allowPrivateHosts:r.allowPrivateHosts}:{}},i=t;for(let s=0;s<=dP;s++){await Vc(i,o);let a={...n,redirect:"manual",...e===globalThis.fetch&&!(r.allowPrivateHosts??uP())?{dispatcher:F6}:{}},l=await lP(e,i,a,r.retry??{});if(!L6.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||i).toString()}catch{return l}await l.body?.cancel().catch(()=>{}),i=d}throw new Pn(`too many redirects (>${dP}) starting from ${t}`)}var M6,O6,$6,Pn,F6,dP,L6,lv=x(()=>{"use strict";G();cP();M6=[["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]],O6=[["::",96],["64:ff9b::",96],["fc00::",7],["fe80::",10]],$6=(()=>{let e=new _6;for(let[t,n]of M6)e.addSubnet(t,n,"ipv4");for(let[t,n]of O6)e.addSubnet(t,n,"ipv6");return e})(),Pn=class extends Error{constructor(t){super(t),this.name="EgressBlockedError"}};F6=new P6({connect:{lookup(e,t,n){pP(e).then(r=>{let o=r.find(s=>iv(s.address));if(o!==void 0){n(new Pn(`refusing to connect to ${e} (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 i=r[0];if(i===void 0){n(new Error(`DNS lookup returned no addresses for ${e}`),"",0);return}n(null,i.address,sv(i.address))},r=>n(r,"",0))}}});dP=20,L6=new Set([301,302,303,307,308])});import{readFileSync as N6}from"node:fs";import{join as B6}from"path";function U6(e){let n=e.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function mP(e,t){return U6(t).test(e)}function W6(e,t){if(e!==void 0){let n=e.trim().toLowerCase();if(n==="1"||n==="true"||n==="yes")return!0;if(n==="0"||n==="false"||n==="no")return!1}if(t!==void 0){if(j6.has(t))return!0;if(H6.has(t))return!1}return!1}function fP(e){return e===void 0||e.trim()===""?[]:e.split(",").map(t=>t.trim().toLowerCase()).filter(t=>t.length>0)}function K6(e){if(e===void 0||e===""||e==="playwright")return"playwright";throw new Error(`AFK_BROWSER_BACKEND: only "playwright" is supported in Phase 1, got: ${e}`)}function gP(e){let t=e===void 0||e.trim()===""?"default":e.trim();return uc(t),t}function G6(e){if(e===void 0)return!1;let t=e.trim().toLowerCase();return t==="1"||t==="true"||t==="yes"}function q6(e){try{return N6(e,"utf8")}catch(t){if(t.code==="ENOENT")return;throw t}}function z6(e,t){let n={...e};if(typeof t.headless=="boolean"&&(n.headless=t.headless),Array.isArray(t.allowedDomains)&&(n.allowedDomains=t.allowedDomains.filter(r=>typeof r=="string").map(r=>r.trim().toLowerCase()).filter(r=>r.length>0)),Array.isArray(t.blockedDomains)&&(n.blockedDomains=t.blockedDomains.filter(r=>typeof r=="string").map(r=>r.trim().toLowerCase()).filter(r=>r.length>0)),typeof t.domSnapshots=="boolean"&&(n.domSnapshots=t.domSnapshots),t.backend==="playwright")n.backend="playwright";else if(t.backend!==void 0)throw new Error(`AFK_BROWSER_BACKEND: only "playwright" is supported in Phase 1, got: ${String(t.backend)}`);return typeof t.defaultProfile=="string"&&(n.defaultProfile=gP(t.defaultProfile)),n}function hP(e){let t=e?.env??v,n=e?.readFileSync??q6,r=e?.surface??t.AGENT_SURFACE,o=W6(t.AFK_BROWSER_HEADLESS,r),i=fP(t.AFK_BROWSER_ALLOWED_DOMAINS),s=fP(t.AFK_BROWSER_BLOCKED_DOMAINS),a=G6(t.AFK_BROWSER_DOM_SNAPSHOTS),l=K6(t.AFK_BROWSER_BACKEND),c=gP(t.AFK_BROWSER_DEFAULT_PROFILE),d={headless:o,allowedDomains:i,blockedDomains:s,domSnapshots:a,backend:l,configPath:null,defaultProfile:c},u=t.AFK_BROWSER_CONFIG,m=u!==void 0&&u.trim()!==""?u.trim():B6(xn(),"browser.json"),f=n(m);if(f===void 0)return d;let g;try{g=JSON.parse(f)}catch(y){throw new Error(`Failed to parse browser config at ${m}: ${String(y)}`)}if(typeof g!="object"||g===null||Array.isArray(g))throw new Error(`Browser config at ${m} must be a JSON object`);let h=z6(d,g);return h.configPath=m,h}function Fm(e,t){let n;try{n=new URL(e).hostname.toLowerCase()}catch{return{allowed:!1,reason:`invalid URL: ${e}`}}for(let r of t.blockedDomains)if(mP(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return t.allowedDomains.length>0&&!t.allowedDomains.some(o=>mP(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var j6,H6,Lm=x(()=>{"use strict";G();z();j6=new Set(["daemon","subagent","telegram","afk"]),H6=new Set(["repl","interactive","cli"])});import{existsSync as J6,readFileSync as Y6}from"node:fs";import{createRequire as V6}from"node:module";import{dirname as X6,join as Q6}from"node:path";function wP(e){if(typeof e=="string")return e;let t=[],n=e;for(let r=0;r<e5&&n instanceof Error;r++)t.push(n.message),n=n.cause;return t.length>0?t.join(" | "):String(e)}function Ut(e){let t=wP(e);return bP.some(n=>t.includes(n))}function t5(){try{let t=V6(import.meta.url).resolve("playwright/package.json"),n=JSON.parse(Y6(t,"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 i=Q6(X6(t),o);return J6(i)?`node ${/\s/.test(i)?`"${i}"`:i} install chromium`:void 0}catch{return}}function Xc(){return yP??=t5()??Z6,yP}function cv(e){return e.includes("install chromium")}function pn(e,t){let n=wP(e),r=t?.latched===!0?` ${n5}`:"";if(n.includes("Executable doesn't exist")){let o="";return t?.headless===!0?o=" This launch was headless, which needs the `chromium_headless_shell-*` build.":t?.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: ${Xc()}.${o}${r}`}return`browser tools require the optional \`playwright\` peer dependency. Install via: pnpm add playwright (then ${Xc()}). Or pick a different tool.${r}`}function Qc(e,t,n=!1){if(!Ut(e))return e;let r=e instanceof Error?e.message:String(e);return new Error(`${r}
|
|
877
877
|
|
|
878
|
-
${pn(e,{headless:t,latched:n})}`,{cause:e})}var bP,Z6,e5,yP,n5,Nm=x(()=>{"use strict";bP=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],Z6="pnpm exec playwright install chromium",e5=4;n5="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 Ei from"node:fs";import Bm from"node:path";import{randomBytes as r5}from"node:crypto";import{chromium as o5}from"playwright";function i5(){try{return"5.83.7"}catch{}try{let e=Bm.resolve(import.meta.dirname,"../../../package.json"),t=Ei.readFileSync(e,"utf8"),n=JSON.parse(t);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var s5,Um,SP=x(()=>{"use strict";Nm();z();be();s5=i5(),Um=class{config;browser;sessions=new Map;launchPromise;launchFailure;shutdownComplete=!1;constructor(t){this.config=t}clearLaunchFailure(){this.launchFailure=void 0}latchLaunchFailure(t){this.launchFailure={error:t}}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=o5.launch({headless:this.config.headless}).then(t=>(this.browser=t,this.launchPromise=void 0,this.clearLaunchFailure(),t)).catch(t=>{this.launchPromise=void 0;let n=Qc(t,this.config.headless,!0);throw this.latchLaunchFailure(n),n}),this.launchPromise)}isBrowserActive(){return this.browser!==void 0&&this.browser.isConnected()}async ensureContext(t){let n=this.sessions.get(t);if(n!==void 0)return n.context;let r=await this.ensureBrowser(),o=this.loadStorageState(this.config.defaultProfile),i=await r.newContext({...this.contextOptions(),...o!==void 0?{storageState:o}:{}}),s={context:i,page:void 0,consoleErrors:0,lastHttpStatus:null,openDialog:void 0};return this.sessions.set(t,s),i}async ensurePage(t){let n=this.sessions.get(t);if(n!==void 0&&n.page!==void 0)return n.page;await this.ensureContext(t);let r=this.sessions.get(t);if(r===void 0)throw new Error(`[BrowserLauncher] session entry disappeared for sessionId=${t}`);if(r.page!==void 0)return r.page;let o=await r.context.newPage();return r.page=o,o.on("console",i=>{i.type()==="error"&&(r.consoleErrors+=1)}),o.on("request",i=>{i.isNavigationRequest()&&i.frame()===o.mainFrame()&&(r.lastHttpStatus=null)}),o.on("response",i=>{i.frame()===o.mainFrame()&&i.request().isNavigationRequest()&&(r.lastHttpStatus=i.status())}),o.on("dialog",i=>{r.openDialog=i}),o}getPage(t){return this.sessions.get(t)?.page}async renderHtml(t,n){let o=await(await this.ensureBrowser()).newContext(this.contextOptions()),i;n.requestGuard!==void 0&&await o.route("**/*",async a=>{try{await n.requestGuard(a.request().url()),await a.continue()}catch(l){i=l,await a.abort("blockedbyclient")}});let s=()=>{o.close().catch(()=>{})};if(n.signal?.aborted===!0)throw await o.close().catch(()=>{}),new Error("render aborted");n.signal!==void 0&&n.signal.addEventListener("abort",s,{once:!0});try{let a=await o.newPage(),l;try{l=await a.goto(t,{timeout:n.timeoutMs,waitUntil:n.waitUntil})}catch(m){throw i??m}if(i!==void 0)throw i;let c=await a.content();if(i!==void 0)throw i;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",s),await o.close().catch(()=>{})}}getConsoleErrorCount(t){return this.sessions.get(t)?.consoleErrors??0}getLastHttpStatus(t){return this.sessions.get(t)?.lastHttpStatus??null}hasOpenDialog(t){return this.sessions.get(t)?.openDialog!==void 0}async dismissDialog(t,n=!0){let r=this.sessions.get(t);if(r===void 0||r.openDialog===void 0)return;let o=r.openDialog;r.openDialog=void 0,n?await o.accept():await o.dismiss()}async closeSession(t){this.clearLaunchFailure();let n=this.sessions.get(t);n!==void 0&&(this.sessions.delete(t),await this.saveStorageState(this.config.defaultProfile,n.context),n.page!==void 0&&await n.page.close().catch(()=>{}),await n.context.close().catch(()=>{}))}async shutdown(){if(this.clearLaunchFailure(),this.shutdownComplete)return;this.shutdownComplete=!0;let t=[...this.sessions.keys()];if(await Promise.all(t.map(n=>this.closeSession(n))),this.browser!==void 0){let n=this.browser;this.browser=void 0,await n.close().catch(()=>{})}}activeSessions(){return this.sessions.size}contextOptions(){return{viewport:{width:1280,height:800},userAgent:`Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 agent-afk/${s5}`}}loadStorageState(t){let n=pc(t);try{if(!Ei.existsSync(n))return;let r=JSON.parse(Ei.readFileSync(n,"utf8"));return W("[browser/vault] restored session",{profile:t,file:n}),r}catch(r){W("[browser/vault] ignoring unreadable vault",{profile:t,file:n,err:r});return}}async saveStorageState(t,n){try{let r=pc(t);if(!Ei.existsSync(r))return;let o=await n.storageState(),i=Bm.join(Bm.dirname(r),`.${Bm.basename(r)}.${process.pid}.${r5(4).toString("hex")}.tmp`);Ei.writeFileSync(i,JSON.stringify(o),{mode:384}),Ei.chmodSync(i,384),Ei.renameSync(i,r),W("[browser/vault] saved session",{profile:t,file:r})}catch(r){W("[browser/vault] save failed",{profile:t,err:r})}}}});import{createHash as a5}from"crypto";function vP(e){return!!(e.role==="textbox"&&e.kind==="password"||e.label&&l5.test(e.label))}function kP(e){return a5("sha256").update(e,"utf8").digest("hex").slice(0,8)}function TP(e){let t=e.replace(/\s+/g," ").trim();return t.length<=80?t:t.slice(0,77)+"..."}var l5,jm=x(()=>{"use strict";l5=/password|secret|token|api[_-]?key|otp|2fa/i});import{createHash as c5}from"node:crypto";function d5(e){return e?e.replace(/\s+/g," ").trim().slice(0,200):""}function u5(e,t,n){return`el_${c5("sha256").update(`${e}:${t}:${n}`).digest("hex").slice(0,6)}`}function p5(e){let t=e.replace(/\s+/g," ").trim(),n=4e3;return t.length<=n?t:t.slice(0,n)+"\u2026[truncated]"}function EP(e){return e.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function RP(e,t){let n=e.role??"",r=e.name??"";xP.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&t.push(e);for(let i of e.children??[])RP(i,t)}async function m5(e){return e.evaluate(t=>{let n=Array.from(document.querySelectorAll(t)),r=[];for(let o of n){let i=o.getBoundingClientRect(),s=o;if(i.width===0&&i.height===0){let d=window.getComputedStyle(s);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(i.left),y:Math.round(i.top),w:Math.round(i.width),h:Math.round(i.height)}})}return r},AP).catch(()=>[])}async function f5(e){return e.evaluate(t=>{let n={button:"button",a:"link",input:"textbox",textarea:"textbox",select:"combobox"},r=Array.from(document.querySelectorAll(t)),o=[];for(let i of r){let s=i.tagName.toLowerCase(),a=i.getAttribute("role")??"",l=i.getAttribute("aria-label")??i.getAttribute("placeholder")??(i.textContent??"").replace(/\s+/g," ").trim().slice(0,100),c=a||(n[s]??"");if(s==="input"){let h=i.type;h==="checkbox"?c="checkbox":h==="radio"?c="radio":h==="button"||h==="submit"||h==="reset"?c="button":h==="search"?c="searchbox":c="textbox"}if(!c)continue;let d="value"in i?i.value:void 0,u=d!==void 0?String(d):void 0,m=i.disabled??!1,f=s==="input"?i.checked:void 0,g={role:c,name:l,disabled:m};u!==void 0&&(g.value=u),f!==void 0&&(g.checked=f),o.push(g)}return o},AP).catch(()=>[])}function g5(e){let n=e.accessibility;return n!==null&&typeof n=="object"?n:null}async function Hm(e,t){let n=t.maxElements??80,r=t.includeHidden??!1,o=[],i=g5(e),s=i?i.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=m5(e),l=e.evaluate(()=>document.body?.innerText??"").catch(()=>""),c=Promise.resolve(e.url()),d=e.title().catch(()=>""),[u,m,f,g,h]=await Promise.all([s,a,l,c,d]),y,b=!1;u!==null?(y=[],RP(u,y)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,y=(await f5(e)).filter(N=>xP.has(N.role??"")));let w=new Map;for(let M of m){let N=EP(M.name),j=w.get(N);(!j||j.bbox.w===0&&M.bbox.w>0)&&w.set(N,M)}let S=y.map(M=>({ax:M,dom:w.get(EP(M.name??""))})),k=r?S:S.filter(M=>M.dom?M.dom.bbox.w>0||M.dom.bbox.h>0:!0);k.sort((M,N)=>{let j=M.dom?.bbox.y??0,B=N.dom?.bbox.y??0;if(j!==B)return j-B;let K=M.dom?.bbox.x??0,_=N.dom?.bbox.x??0;return K-_}),k.length>200&&o.push("page has 200+ interactive elements; consider scoping");let A=k.slice(0,n).map((M,N)=>{let j=M.ax.role??"generic",B=M.ax.name??"",K=u5(j,B,N),_=M.dom?.bbox??{x:0,y:0,w:0,h:0},$=M.dom?.type??null,I=null;M.ax.value!==void 0&&M.ax.value!==null&&(I=String(M.ax.value)),M.ax.checked!==void 0&&(I=String(M.ax.checked)),vP({role:j,kind:$})&&(I="[redacted]");let F={disabled:M.ax.disabled??!1};M.ax.checked!==void 0&&(F.checked=M.ax.checked===!0||M.ax.checked==="mixed"),M.ax.selected!==void 0&&(F.selected=M.ax.selected),M.ax.expanded!==void 0&&(F.expanded=M.ax.expanded);let P;M.dom?.testId?P=`[data-testid="${M.dom.testId}"]`:M.dom?.id&&(P=`#${M.dom.id}`);let H={id:K,role:j,label:d5(B),kind:$,value:I,state:F,bbox:_};return P!==void 0&&(H.selector=P),H}),O="idle";try{let M=await e.evaluate(()=>document.readyState);M==="loading"?O="loading":M==="interactive"?O="navigating":O="idle"}catch{O="navigating"}O!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),b&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let E=p5(f),D=`obs_${t.observationCounter.toString(36)}`,C=new Date().toISOString();return{observationId:D,url:g,title:h,textSummary:E,interactive:A,status:{httpStatus:t.httpStatus??null,loadingState:O,hasDialog:t.hasDialog??!1,consoleErrors:t.consoleErrors??0},warnings:o,screenshotPath:t.screenshotPath??null,capturedAt:C}}var xP,AP,CP=x(()=>{"use strict";jm();xP=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);AP="a[href], button, input, select, textarea, [role], [tabindex], label"});async function _P(e,t){try{let n=await e.nth(t).evaluate(s=>{let a=s,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}:${t}`,o=0;for(let s=0;s<r.length;s++)o=o*31+r.charCodeAt(s)>>>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 dv(e,t){let n=Math.min(t,5);return(await Promise.all(Array.from({length:n},(o,i)=>_P(e,i)))).filter(o=>o!==null)}async function h5(e){let t=new Set,n=[];for(let{loc:r,count:o}of e)for(let i=0;i<o;i++){let s;try{s=await r.nth(i).evaluate(a=>{let l=a,c=l.getBoundingClientRect();return`${l.tagName}@${Math.round(c.x)},${Math.round(c.y)}`})}catch{continue}t.has(s)||(t.add(s),n.push({key:s,locator:r,index:i}))}return n}async function uv(e,t,n){switch(t.kind){case"element_id":return y5(e,t,n);case"selector":return b5(e,t);case"semantic":return w5(e,t)}}async function y5(e,t,n){let r=n.get(t.elementId);if(r===void 0)return{outcome:"not_found",query:t};if(r.selector!==void 0){let l=e.locator(r.selector);if(await l.count()===1)return{outcome:"resolved",locator:l}}let o=e.getByRole(r.role,{name:r.label,exact:!0}),i=await o.count();if(i===0)return{outcome:"not_found",query:t};if(i===1)return{outcome:"resolved",locator:o};let s=await dv(o,i);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:s}}async function b5(e,t){let n=e.locator(t.selector),r=await n.count();if(r===0)return{outcome:"not_found",query:t};if(r===1)return{outcome:"resolved",locator:n};let o=await dv(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${t.selector}]`},candidates:o}}async function w5(e,t){return t.role!==void 0?S5(e,t.text,t.role):v5(e,t.text,t)}async function S5(e,t,n){let r=e.getByRole(n,{name:t}),o=await r.count();if(o===0)return{outcome:"not_found",query:{kind:"semantic",text:t,role:n}};if(o===1)return{outcome:"resolved",locator:r};let i=await dv(r,o);return{outcome:"ambiguous_target",query:{text:t,role:n},candidates:i}}async function v5(e,t,n){let r=e.getByRole("button",{name:t}),o=e.getByRole("link",{name:t}),i=e.getByLabel(t,{exact:!1}),[s,a,l]=await Promise.all([r.count(),o.count(),i.count()]);if(s+a+l===0)return{outcome:"not_found",query:n};let d=[];s>0&&d.push({loc:r,count:s}),a>0&&d.push({loc:o,count:a}),l>0&&d.push({loc:i,count:l});let u=await h5(d);if(u.length===0)return{outcome:"not_found",query:n};if(u.length===1){let h=u[0];return h===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:h.locator.nth(h.index)}}let m=u.slice(0,5),f=[];for(let h=0;h<m.length;h++){let y=m[h];if(y===void 0)continue;let b=await _P(y.locator,y.index);if(b!==null){let w=`${b.role}:${b.label}:${h}`,S=0;for(let k=0;k<w.length;k++)S=S*31+w.charCodeAt(k)>>>0;f.push({...b,id:`el_${S.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:t},candidates:f}}var IP=x(()=>{"use strict"});async function pv(e,t,n,r){let o=e.url();if(o===n)return null;let i=Fm(o,t);if(i.allowed)return null;try{await e.goBack()}catch{await r()}return{outcome:"blocked_by_policy",url:o,reason:i.reason}}var PP=x(()=>{"use strict";Lm()});import{randomBytes as k5}from"crypto";import{mkdir as T5,stat as E5,writeFile as x5}from"fs/promises";import{join as mv}from"path";import{gzip as R5}from"zlib";import{promisify as A5}from"util";function C5(e){return mv(ni(e),"browser")}function _5(e){return mv(C5(e),"screenshots")}function I5(){return new Date().toISOString().replace(/[:.]/g,"-")}function P5(){return k5(3).toString("hex")}async function fv(e,t,n){if(t.length>MP)throw new Error(`writeScreenshotSidecar: buffer exceeds ${MP} byte cap (received ${t.length} bytes). Refusing to write oversized screenshot.`);let r=_5(e);await T5(r,{recursive:!0});let o=`${I5()}-${P5()}-${n}.png`,i=mv(r,o);await x5(i,t);let{size:s}=await E5(i);return{path:i,bytes:s}}var O_e,MP,OP=x(()=>{"use strict";z();jm();O_e=A5(R5);MP=5*1024*1024});var DP={};ip(DP,{PlaywrightProvider:()=>gv});function $P(e){switch(e.kind){case"semantic":return e.role!==void 0?`semantic('${e.text}', role='${e.role}')`:`semantic('${e.text}')`;case"element_id":return`element_id(${e.elementId})`;case"selector":return`selector(${e.selector})`}}var gv,FP=x(()=>{"use strict";SP();CP();IP();Lm();PP();OP();gv=class{name="playwright";config;launcher;sessions=new Map;constructor(t){this.config=t,this.launcher=new Um(t)}async open(t){let n=Fm(t.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:t.url,reason:n.reason};let{sessionId:r}=t,o=await this.launcher.ensurePage(r),i=this.ensureSessionState(r),s=null,a=null;try{await o.goto(t.url,{timeout:t.timeoutMs??3e4,waitUntil:t.waitFor??"load"})}catch(u){a=u}let l=o.url();if(!(a!==null&&(l===""||l==="about:blank"))){let u=await pv(o,this.config,t.url,()=>this.close({sessionId:r}));if(u!==null)return u}(t.screenshot===!0||a!==null)&&(s=await this.captureScreenshot(o,r,"browser_open")),i.observationCounter+=1;let d=await Hm(o,{observationCounter:i.observationCounter,screenshotPath:s,consoleErrors:this.launcher.getConsoleErrorCount(r),httpStatus:this.launcher.getLastHttpStatus(r),hasDialog:this.launcher.hasOpenDialog(r)});if(this.updateSessionFromObservation(i,d.interactive,d.url,d.title,"browser_open"),a!==null)throw a;return d}async observe(t){let{sessionId:n}=t,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_observe: no page open for session ${n}`);let o=this.ensureSessionState(n),i=null;t.screenshot===!0&&(i=await this.captureScreenshot(r,n,"browser_observe")),o.observationCounter+=1;let s=await Hm(r,{observationCounter:o.observationCounter,screenshotPath:i,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n),includeHidden:t.includeHidden,maxElements:t.maxElements});return this.updateSessionFromObservation(o,s.interactive,s.url,s.title,"browser_observe"),s}async act(t){let{sessionId:n}=t,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_act: no page open for session ${n}`);let o=this.ensureSessionState(n),i=r.url(),s=t.timeoutMs??3e4,a=await uv(r,t.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${$P(t.target)}`);if(a.outcome==="ambiguous_target")return a;let{locator:l}=a,c=null,d=async()=>{switch(t.action){case"click":await l.click({timeout:s});break;case"fill":await l.fill(t.value??"");break;case"press":await l.press(t.value??"");break;case"select":await l.selectOption(t.value??"");break;case"hover":await l.hover({timeout:s});break;case"scroll_to":await l.scrollIntoViewIfNeeded({timeout:s});break;case"wait_for":await l.waitFor({timeout:s,state:"visible"});break}};try{await d()}catch(h){if(h instanceof Error&&/navigation|net::ERR/i.test(h.message))try{await d()}catch(y){c=y}else c=h}let u=await pv(r,this.config,i,()=>this.close({sessionId:n}));if(u!==null)return u;let m=null;(t.screenshot===!0||c!==null)&&(m=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await Hm(r,{observationCounter:o.observationCounter,screenshotPath:m,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),g=`browser_act:${t.action}`;if(this.updateSessionFromObservation(o,f.interactive,f.url,f.title,g),c!==null)throw c;return f}async render(t){return this.launcher.renderHtml(t.url,{timeoutMs:t.timeoutMs??3e4,waitUntil:t.waitFor??"load",signal:t.signal,requestGuard:t.requestGuard})}async screenshot(t){let{sessionId:n}=t,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_screenshot: no page open for session ${n}`);let o=this.ensureSessionState(n),i;if(t.target!==void 0){let d=await uv(r,t.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${$P(t.target)}`);if(d.outcome==="ambiguous_target")throw new Error("screenshot target ambiguous; specify element_id or selector");i=await d.locator.screenshot()}else i=await r.screenshot({fullPage:t.fullPage??!1});let{path:s,bytes:a}=await fv(n,i,"browser_screenshot"),l=0,c=0;if(t.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:s,bytes:a,width:l,height:c,dataBase64:i.toString("base64"),mediaType:"image/png"}}async extract(t){throw new Error("browser_extract not implemented in Phase 1")}async close(t){await this.launcher.closeSession(t.sessionId),this.sessions.delete(t.sessionId)}describe(t){let n=this.sessions.get(t);if(n===void 0)return null;let r=this.launcher.getPage(t);return{active:r!==void 0,url:n.currentUrl,title:n.currentTitle,lastAction:n.lastAction,lastActionAt:n.lastActionAt,openTabs:r!==void 0?1:0}}async shutdown(){this.sessions.clear(),await this.launcher.shutdown()}ensureSessionState(t){let n=this.sessions.get(t);if(n!==void 0)return n;let r={observationCounter:0,knownElements:new Map,lastAction:null,lastActionAt:null,currentUrl:null,currentTitle:null};return this.sessions.set(t,r),r}updateSessionFromObservation(t,n,r,o,i){t.knownElements=new Map(n.map(s=>[s.id,s])),t.currentUrl=r,t.currentTitle=o,t.lastAction=i,t.lastActionAt=new Date().toISOString()}async captureScreenshot(t,n,r){try{let o=await t.screenshot({fullPage:!1}),{path:i}=await fv(n,o,r);return i}catch{return null}}}});var Ri={};ip(Ri,{__resetBrowserRegistryForTests:()=>F5,browserProviderActive:()=>$5,closeBrowserProvider:()=>hv,getBrowserProvider:()=>O5,peekBrowserProvider:()=>D5});function LP(){Promise.resolve(hv()).then(()=>{process.exit(130)})}function NP(){Promise.resolve(hv()).then(()=>{process.exit(143)})}function BP(){or=null}function M5(){Wm||(process.on("SIGINT",LP),process.on("SIGTERM",NP),process.on("exit",BP),Wm=!0)}function UP(){Wm&&(process.removeListener("SIGINT",LP),process.removeListener("SIGTERM",NP),process.removeListener("exit",BP),Wm=!1)}async function O5(e){return or!==null?or:(xi!==null||(xi=(async()=>{let{PlaywrightProvider:t}=await Promise.resolve().then(()=>(FP(),DP)),n=hP(e),r=new t(n);return M5(),or=r,xi=null,r})()),xi)}async function hv(){if(or===null)return;let e=or;or=null,xi=null,UP(),await e.shutdown()}function $5(){return or!==null}function D5(){return or}function F5(){or=null,xi=null,UP()}var or,xi,Wm,Ai=x(()=>{"use strict";Lm();or=null,xi=null,Wm=!1});async function jP(e,t){try{return await iP(e,t)}catch(n){return W("[web/scrape] extraction failed",{url:t,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function H5(e,t){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(Ai(),Ri));return(await n()).render({url:e,timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:t.requestGuard})}async function HP(e,t){let n=t.fetchFn??globalThis.fetch,r=t.renderFn??H5,o=t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{},i=null,s=e,a=null,l=null;try{let d=await Dm(n,e,{headers:j5,signal:t.signal},o);a=d.status,s=d.url||e;let u=d.headers.get("content-type")??"";if(d.ok){if(U5.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 m=await d.text();if(B5.test(u)&&!N5.test(u))return{title:"",markdown:m.trim(),finalUrl:s,usedRender:!1};if(i=await jP(m,s),t.signal.aborted)throw t.signal.reason??new Error("aborted")}}catch(d){if(t.signal.aborted||d instanceof Pn||d instanceof Error&&d.message.startsWith("web_scrape markdown mode received binary"))throw d;l=d}if(!(i===null||i.textLength<200)&&i!==null)return{title:i.title,markdown:i.markdown,finalUrl:s,usedRender:!1};try{await Vc(e,o);let d=await r(e,{timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:m=>Vc(m,o)});d.finalUrl!==e&&/^https?:\/\//i.test(d.finalUrl)&&await Vc(d.finalUrl,o);let u=await jP(d.html,d.finalUrl);if(t.signal.aborted)throw t.signal.reason??new Error("aborted");if(i===null||u.textLength>=i.textLength)return{title:u.title,markdown:u.markdown,finalUrl:d.finalUrl,usedRender:!0}}catch(d){if(t.signal.aborted||d instanceof Pn)throw d;if(i===null){let u=d instanceof Error?d.message:String(d),m=l instanceof Error?l.message:`HTTP ${a??"error"}`,f=new Error(`web_scrape could not retrieve ${e}: fetch failed (${m}) and render failed (${u}).`);throw f.cause=d,f}}if(i!==null)return{title:i.title,markdown:i.markdown,finalUrl:s,usedRender:!1};throw new Error(`web_scrape could not retrieve any content from ${e} (HTTP ${a??"error"}).`)}var N5,B5,U5,j5,WP=x(()=>{"use strict";sP();lv();be();N5=/(text\/html|application\/xhtml\+xml)/i,B5=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,U5=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,j5={"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 G5(e){let t=e.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let i=await t(W5,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json","x-api-key":e.apiKey,"User-Agent":"agent-afk/web_scrape"},body:JSON.stringify({query:n,type:"auto",numResults:Math.min(Math.max(r,1),K5),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!i.ok){let l="";try{let d=await i.text(),u=Ir(d);u&&(l=`: ${u.length>200?u.slice(0,200)+"\u2026":u}`)}catch{}let c=i.statusText?` ${i.statusText}`:"";throw new Error(`Exa Search HTTP ${i.status}${c}${l}`)}let s;try{s=await i.json()}catch(l){throw new Error(`Exa Search response was not JSON: ${l instanceof Error?l.message:String(l)}`)}return(s.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 KP(e){return e.exaApiKey!==void 0&&e.exaApiKey.trim()!==""?G5({apiKey:e.exaApiKey,fetchFn:e.fetchFn}):{error:'web_scrape search mode requires a search backend. Set EXA_API_KEY (free tier at https://exa.ai) to enable it. Use mode: "markdown" to read a known URL, or mode: "raw" for a direct fetch.'}}function GP(e,t){if(t.length===0)return`# Search results for "${e}"
|
|
878
|
+
${pn(e,{headless:t,latched:n})}`,{cause:e})}var bP,Z6,e5,yP,n5,Nm=x(()=>{"use strict";bP=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],Z6="pnpm exec playwright install chromium",e5=4;n5="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 Ei from"node:fs";import Bm from"node:path";import{randomBytes as r5}from"node:crypto";import{chromium as o5}from"playwright";function i5(){try{return"5.83.8"}catch{}try{let e=Bm.resolve(import.meta.dirname,"../../../package.json"),t=Ei.readFileSync(e,"utf8"),n=JSON.parse(t);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var s5,Um,SP=x(()=>{"use strict";Nm();z();be();s5=i5(),Um=class{config;browser;sessions=new Map;launchPromise;launchFailure;shutdownComplete=!1;constructor(t){this.config=t}clearLaunchFailure(){this.launchFailure=void 0}latchLaunchFailure(t){this.launchFailure={error:t}}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=o5.launch({headless:this.config.headless}).then(t=>(this.browser=t,this.launchPromise=void 0,this.clearLaunchFailure(),t)).catch(t=>{this.launchPromise=void 0;let n=Qc(t,this.config.headless,!0);throw this.latchLaunchFailure(n),n}),this.launchPromise)}isBrowserActive(){return this.browser!==void 0&&this.browser.isConnected()}async ensureContext(t){let n=this.sessions.get(t);if(n!==void 0)return n.context;let r=await this.ensureBrowser(),o=this.loadStorageState(this.config.defaultProfile),i=await r.newContext({...this.contextOptions(),...o!==void 0?{storageState:o}:{}}),s={context:i,page:void 0,consoleErrors:0,lastHttpStatus:null,openDialog:void 0};return this.sessions.set(t,s),i}async ensurePage(t){let n=this.sessions.get(t);if(n!==void 0&&n.page!==void 0)return n.page;await this.ensureContext(t);let r=this.sessions.get(t);if(r===void 0)throw new Error(`[BrowserLauncher] session entry disappeared for sessionId=${t}`);if(r.page!==void 0)return r.page;let o=await r.context.newPage();return r.page=o,o.on("console",i=>{i.type()==="error"&&(r.consoleErrors+=1)}),o.on("request",i=>{i.isNavigationRequest()&&i.frame()===o.mainFrame()&&(r.lastHttpStatus=null)}),o.on("response",i=>{i.frame()===o.mainFrame()&&i.request().isNavigationRequest()&&(r.lastHttpStatus=i.status())}),o.on("dialog",i=>{r.openDialog=i}),o}getPage(t){return this.sessions.get(t)?.page}async renderHtml(t,n){let o=await(await this.ensureBrowser()).newContext(this.contextOptions()),i;n.requestGuard!==void 0&&await o.route("**/*",async a=>{try{await n.requestGuard(a.request().url()),await a.continue()}catch(l){i=l,await a.abort("blockedbyclient")}});let s=()=>{o.close().catch(()=>{})};if(n.signal?.aborted===!0)throw await o.close().catch(()=>{}),new Error("render aborted");n.signal!==void 0&&n.signal.addEventListener("abort",s,{once:!0});try{let a=await o.newPage(),l;try{l=await a.goto(t,{timeout:n.timeoutMs,waitUntil:n.waitUntil})}catch(m){throw i??m}if(i!==void 0)throw i;let c=await a.content();if(i!==void 0)throw i;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",s),await o.close().catch(()=>{})}}getConsoleErrorCount(t){return this.sessions.get(t)?.consoleErrors??0}getLastHttpStatus(t){return this.sessions.get(t)?.lastHttpStatus??null}hasOpenDialog(t){return this.sessions.get(t)?.openDialog!==void 0}async dismissDialog(t,n=!0){let r=this.sessions.get(t);if(r===void 0||r.openDialog===void 0)return;let o=r.openDialog;r.openDialog=void 0,n?await o.accept():await o.dismiss()}async closeSession(t){this.clearLaunchFailure();let n=this.sessions.get(t);n!==void 0&&(this.sessions.delete(t),await this.saveStorageState(this.config.defaultProfile,n.context),n.page!==void 0&&await n.page.close().catch(()=>{}),await n.context.close().catch(()=>{}))}async shutdown(){if(this.clearLaunchFailure(),this.shutdownComplete)return;this.shutdownComplete=!0;let t=[...this.sessions.keys()];if(await Promise.all(t.map(n=>this.closeSession(n))),this.browser!==void 0){let n=this.browser;this.browser=void 0,await n.close().catch(()=>{})}}activeSessions(){return this.sessions.size}contextOptions(){return{viewport:{width:1280,height:800},userAgent:`Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 agent-afk/${s5}`}}loadStorageState(t){let n=pc(t);try{if(!Ei.existsSync(n))return;let r=JSON.parse(Ei.readFileSync(n,"utf8"));return W("[browser/vault] restored session",{profile:t,file:n}),r}catch(r){W("[browser/vault] ignoring unreadable vault",{profile:t,file:n,err:r});return}}async saveStorageState(t,n){try{let r=pc(t);if(!Ei.existsSync(r))return;let o=await n.storageState(),i=Bm.join(Bm.dirname(r),`.${Bm.basename(r)}.${process.pid}.${r5(4).toString("hex")}.tmp`);Ei.writeFileSync(i,JSON.stringify(o),{mode:384}),Ei.chmodSync(i,384),Ei.renameSync(i,r),W("[browser/vault] saved session",{profile:t,file:r})}catch(r){W("[browser/vault] save failed",{profile:t,err:r})}}}});import{createHash as a5}from"crypto";function vP(e){return!!(e.role==="textbox"&&e.kind==="password"||e.label&&l5.test(e.label))}function kP(e){return a5("sha256").update(e,"utf8").digest("hex").slice(0,8)}function TP(e){let t=e.replace(/\s+/g," ").trim();return t.length<=80?t:t.slice(0,77)+"..."}var l5,jm=x(()=>{"use strict";l5=/password|secret|token|api[_-]?key|otp|2fa/i});import{createHash as c5}from"node:crypto";function d5(e){return e?e.replace(/\s+/g," ").trim().slice(0,200):""}function u5(e,t,n){return`el_${c5("sha256").update(`${e}:${t}:${n}`).digest("hex").slice(0,6)}`}function p5(e){let t=e.replace(/\s+/g," ").trim(),n=4e3;return t.length<=n?t:t.slice(0,n)+"\u2026[truncated]"}function EP(e){return e.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function RP(e,t){let n=e.role??"",r=e.name??"";xP.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&t.push(e);for(let i of e.children??[])RP(i,t)}async function m5(e){return e.evaluate(t=>{let n=Array.from(document.querySelectorAll(t)),r=[];for(let o of n){let i=o.getBoundingClientRect(),s=o;if(i.width===0&&i.height===0){let d=window.getComputedStyle(s);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(i.left),y:Math.round(i.top),w:Math.round(i.width),h:Math.round(i.height)}})}return r},AP).catch(()=>[])}async function f5(e){return e.evaluate(t=>{let n={button:"button",a:"link",input:"textbox",textarea:"textbox",select:"combobox"},r=Array.from(document.querySelectorAll(t)),o=[];for(let i of r){let s=i.tagName.toLowerCase(),a=i.getAttribute("role")??"",l=i.getAttribute("aria-label")??i.getAttribute("placeholder")??(i.textContent??"").replace(/\s+/g," ").trim().slice(0,100),c=a||(n[s]??"");if(s==="input"){let h=i.type;h==="checkbox"?c="checkbox":h==="radio"?c="radio":h==="button"||h==="submit"||h==="reset"?c="button":h==="search"?c="searchbox":c="textbox"}if(!c)continue;let d="value"in i?i.value:void 0,u=d!==void 0?String(d):void 0,m=i.disabled??!1,f=s==="input"?i.checked:void 0,g={role:c,name:l,disabled:m};u!==void 0&&(g.value=u),f!==void 0&&(g.checked=f),o.push(g)}return o},AP).catch(()=>[])}function g5(e){let n=e.accessibility;return n!==null&&typeof n=="object"?n:null}async function Hm(e,t){let n=t.maxElements??80,r=t.includeHidden??!1,o=[],i=g5(e),s=i?i.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=m5(e),l=e.evaluate(()=>document.body?.innerText??"").catch(()=>""),c=Promise.resolve(e.url()),d=e.title().catch(()=>""),[u,m,f,g,h]=await Promise.all([s,a,l,c,d]),y,b=!1;u!==null?(y=[],RP(u,y)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,y=(await f5(e)).filter(N=>xP.has(N.role??"")));let w=new Map;for(let M of m){let N=EP(M.name),j=w.get(N);(!j||j.bbox.w===0&&M.bbox.w>0)&&w.set(N,M)}let S=y.map(M=>({ax:M,dom:w.get(EP(M.name??""))})),k=r?S:S.filter(M=>M.dom?M.dom.bbox.w>0||M.dom.bbox.h>0:!0);k.sort((M,N)=>{let j=M.dom?.bbox.y??0,B=N.dom?.bbox.y??0;if(j!==B)return j-B;let K=M.dom?.bbox.x??0,_=N.dom?.bbox.x??0;return K-_}),k.length>200&&o.push("page has 200+ interactive elements; consider scoping");let A=k.slice(0,n).map((M,N)=>{let j=M.ax.role??"generic",B=M.ax.name??"",K=u5(j,B,N),_=M.dom?.bbox??{x:0,y:0,w:0,h:0},$=M.dom?.type??null,I=null;M.ax.value!==void 0&&M.ax.value!==null&&(I=String(M.ax.value)),M.ax.checked!==void 0&&(I=String(M.ax.checked)),vP({role:j,kind:$})&&(I="[redacted]");let F={disabled:M.ax.disabled??!1};M.ax.checked!==void 0&&(F.checked=M.ax.checked===!0||M.ax.checked==="mixed"),M.ax.selected!==void 0&&(F.selected=M.ax.selected),M.ax.expanded!==void 0&&(F.expanded=M.ax.expanded);let P;M.dom?.testId?P=`[data-testid="${M.dom.testId}"]`:M.dom?.id&&(P=`#${M.dom.id}`);let H={id:K,role:j,label:d5(B),kind:$,value:I,state:F,bbox:_};return P!==void 0&&(H.selector=P),H}),O="idle";try{let M=await e.evaluate(()=>document.readyState);M==="loading"?O="loading":M==="interactive"?O="navigating":O="idle"}catch{O="navigating"}O!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),b&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let E=p5(f),D=`obs_${t.observationCounter.toString(36)}`,C=new Date().toISOString();return{observationId:D,url:g,title:h,textSummary:E,interactive:A,status:{httpStatus:t.httpStatus??null,loadingState:O,hasDialog:t.hasDialog??!1,consoleErrors:t.consoleErrors??0},warnings:o,screenshotPath:t.screenshotPath??null,capturedAt:C}}var xP,AP,CP=x(()=>{"use strict";jm();xP=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);AP="a[href], button, input, select, textarea, [role], [tabindex], label"});async function _P(e,t){try{let n=await e.nth(t).evaluate(s=>{let a=s,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}:${t}`,o=0;for(let s=0;s<r.length;s++)o=o*31+r.charCodeAt(s)>>>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 dv(e,t){let n=Math.min(t,5);return(await Promise.all(Array.from({length:n},(o,i)=>_P(e,i)))).filter(o=>o!==null)}async function h5(e){let t=new Set,n=[];for(let{loc:r,count:o}of e)for(let i=0;i<o;i++){let s;try{s=await r.nth(i).evaluate(a=>{let l=a,c=l.getBoundingClientRect();return`${l.tagName}@${Math.round(c.x)},${Math.round(c.y)}`})}catch{continue}t.has(s)||(t.add(s),n.push({key:s,locator:r,index:i}))}return n}async function uv(e,t,n){switch(t.kind){case"element_id":return y5(e,t,n);case"selector":return b5(e,t);case"semantic":return w5(e,t)}}async function y5(e,t,n){let r=n.get(t.elementId);if(r===void 0)return{outcome:"not_found",query:t};if(r.selector!==void 0){let l=e.locator(r.selector);if(await l.count()===1)return{outcome:"resolved",locator:l}}let o=e.getByRole(r.role,{name:r.label,exact:!0}),i=await o.count();if(i===0)return{outcome:"not_found",query:t};if(i===1)return{outcome:"resolved",locator:o};let s=await dv(o,i);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:s}}async function b5(e,t){let n=e.locator(t.selector),r=await n.count();if(r===0)return{outcome:"not_found",query:t};if(r===1)return{outcome:"resolved",locator:n};let o=await dv(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${t.selector}]`},candidates:o}}async function w5(e,t){return t.role!==void 0?S5(e,t.text,t.role):v5(e,t.text,t)}async function S5(e,t,n){let r=e.getByRole(n,{name:t}),o=await r.count();if(o===0)return{outcome:"not_found",query:{kind:"semantic",text:t,role:n}};if(o===1)return{outcome:"resolved",locator:r};let i=await dv(r,o);return{outcome:"ambiguous_target",query:{text:t,role:n},candidates:i}}async function v5(e,t,n){let r=e.getByRole("button",{name:t}),o=e.getByRole("link",{name:t}),i=e.getByLabel(t,{exact:!1}),[s,a,l]=await Promise.all([r.count(),o.count(),i.count()]);if(s+a+l===0)return{outcome:"not_found",query:n};let d=[];s>0&&d.push({loc:r,count:s}),a>0&&d.push({loc:o,count:a}),l>0&&d.push({loc:i,count:l});let u=await h5(d);if(u.length===0)return{outcome:"not_found",query:n};if(u.length===1){let h=u[0];return h===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:h.locator.nth(h.index)}}let m=u.slice(0,5),f=[];for(let h=0;h<m.length;h++){let y=m[h];if(y===void 0)continue;let b=await _P(y.locator,y.index);if(b!==null){let w=`${b.role}:${b.label}:${h}`,S=0;for(let k=0;k<w.length;k++)S=S*31+w.charCodeAt(k)>>>0;f.push({...b,id:`el_${S.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:t},candidates:f}}var IP=x(()=>{"use strict"});async function pv(e,t,n,r){let o=e.url();if(o===n)return null;let i=Fm(o,t);if(i.allowed)return null;try{await e.goBack()}catch{await r()}return{outcome:"blocked_by_policy",url:o,reason:i.reason}}var PP=x(()=>{"use strict";Lm()});import{randomBytes as k5}from"crypto";import{mkdir as T5,stat as E5,writeFile as x5}from"fs/promises";import{join as mv}from"path";import{gzip as R5}from"zlib";import{promisify as A5}from"util";function C5(e){return mv(ni(e),"browser")}function _5(e){return mv(C5(e),"screenshots")}function I5(){return new Date().toISOString().replace(/[:.]/g,"-")}function P5(){return k5(3).toString("hex")}async function fv(e,t,n){if(t.length>MP)throw new Error(`writeScreenshotSidecar: buffer exceeds ${MP} byte cap (received ${t.length} bytes). Refusing to write oversized screenshot.`);let r=_5(e);await T5(r,{recursive:!0});let o=`${I5()}-${P5()}-${n}.png`,i=mv(r,o);await x5(i,t);let{size:s}=await E5(i);return{path:i,bytes:s}}var O_e,MP,OP=x(()=>{"use strict";z();jm();O_e=A5(R5);MP=5*1024*1024});var DP={};ip(DP,{PlaywrightProvider:()=>gv});function $P(e){switch(e.kind){case"semantic":return e.role!==void 0?`semantic('${e.text}', role='${e.role}')`:`semantic('${e.text}')`;case"element_id":return`element_id(${e.elementId})`;case"selector":return`selector(${e.selector})`}}var gv,FP=x(()=>{"use strict";SP();CP();IP();Lm();PP();OP();gv=class{name="playwright";config;launcher;sessions=new Map;constructor(t){this.config=t,this.launcher=new Um(t)}async open(t){let n=Fm(t.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:t.url,reason:n.reason};let{sessionId:r}=t,o=await this.launcher.ensurePage(r),i=this.ensureSessionState(r),s=null,a=null;try{await o.goto(t.url,{timeout:t.timeoutMs??3e4,waitUntil:t.waitFor??"load"})}catch(u){a=u}let l=o.url();if(!(a!==null&&(l===""||l==="about:blank"))){let u=await pv(o,this.config,t.url,()=>this.close({sessionId:r}));if(u!==null)return u}(t.screenshot===!0||a!==null)&&(s=await this.captureScreenshot(o,r,"browser_open")),i.observationCounter+=1;let d=await Hm(o,{observationCounter:i.observationCounter,screenshotPath:s,consoleErrors:this.launcher.getConsoleErrorCount(r),httpStatus:this.launcher.getLastHttpStatus(r),hasDialog:this.launcher.hasOpenDialog(r)});if(this.updateSessionFromObservation(i,d.interactive,d.url,d.title,"browser_open"),a!==null)throw a;return d}async observe(t){let{sessionId:n}=t,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_observe: no page open for session ${n}`);let o=this.ensureSessionState(n),i=null;t.screenshot===!0&&(i=await this.captureScreenshot(r,n,"browser_observe")),o.observationCounter+=1;let s=await Hm(r,{observationCounter:o.observationCounter,screenshotPath:i,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n),includeHidden:t.includeHidden,maxElements:t.maxElements});return this.updateSessionFromObservation(o,s.interactive,s.url,s.title,"browser_observe"),s}async act(t){let{sessionId:n}=t,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_act: no page open for session ${n}`);let o=this.ensureSessionState(n),i=r.url(),s=t.timeoutMs??3e4,a=await uv(r,t.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${$P(t.target)}`);if(a.outcome==="ambiguous_target")return a;let{locator:l}=a,c=null,d=async()=>{switch(t.action){case"click":await l.click({timeout:s});break;case"fill":await l.fill(t.value??"");break;case"press":await l.press(t.value??"");break;case"select":await l.selectOption(t.value??"");break;case"hover":await l.hover({timeout:s});break;case"scroll_to":await l.scrollIntoViewIfNeeded({timeout:s});break;case"wait_for":await l.waitFor({timeout:s,state:"visible"});break}};try{await d()}catch(h){if(h instanceof Error&&/navigation|net::ERR/i.test(h.message))try{await d()}catch(y){c=y}else c=h}let u=await pv(r,this.config,i,()=>this.close({sessionId:n}));if(u!==null)return u;let m=null;(t.screenshot===!0||c!==null)&&(m=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await Hm(r,{observationCounter:o.observationCounter,screenshotPath:m,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),g=`browser_act:${t.action}`;if(this.updateSessionFromObservation(o,f.interactive,f.url,f.title,g),c!==null)throw c;return f}async render(t){return this.launcher.renderHtml(t.url,{timeoutMs:t.timeoutMs??3e4,waitUntil:t.waitFor??"load",signal:t.signal,requestGuard:t.requestGuard})}async screenshot(t){let{sessionId:n}=t,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_screenshot: no page open for session ${n}`);let o=this.ensureSessionState(n),i;if(t.target!==void 0){let d=await uv(r,t.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${$P(t.target)}`);if(d.outcome==="ambiguous_target")throw new Error("screenshot target ambiguous; specify element_id or selector");i=await d.locator.screenshot()}else i=await r.screenshot({fullPage:t.fullPage??!1});let{path:s,bytes:a}=await fv(n,i,"browser_screenshot"),l=0,c=0;if(t.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:s,bytes:a,width:l,height:c,dataBase64:i.toString("base64"),mediaType:"image/png"}}async extract(t){throw new Error("browser_extract not implemented in Phase 1")}async close(t){await this.launcher.closeSession(t.sessionId),this.sessions.delete(t.sessionId)}describe(t){let n=this.sessions.get(t);if(n===void 0)return null;let r=this.launcher.getPage(t);return{active:r!==void 0,url:n.currentUrl,title:n.currentTitle,lastAction:n.lastAction,lastActionAt:n.lastActionAt,openTabs:r!==void 0?1:0}}async shutdown(){this.sessions.clear(),await this.launcher.shutdown()}ensureSessionState(t){let n=this.sessions.get(t);if(n!==void 0)return n;let r={observationCounter:0,knownElements:new Map,lastAction:null,lastActionAt:null,currentUrl:null,currentTitle:null};return this.sessions.set(t,r),r}updateSessionFromObservation(t,n,r,o,i){t.knownElements=new Map(n.map(s=>[s.id,s])),t.currentUrl=r,t.currentTitle=o,t.lastAction=i,t.lastActionAt=new Date().toISOString()}async captureScreenshot(t,n,r){try{let o=await t.screenshot({fullPage:!1}),{path:i}=await fv(n,o,r);return i}catch{return null}}}});var Ri={};ip(Ri,{__resetBrowserRegistryForTests:()=>F5,browserProviderActive:()=>$5,closeBrowserProvider:()=>hv,getBrowserProvider:()=>O5,peekBrowserProvider:()=>D5});function LP(){Promise.resolve(hv()).then(()=>{process.exit(130)})}function NP(){Promise.resolve(hv()).then(()=>{process.exit(143)})}function BP(){or=null}function M5(){Wm||(process.on("SIGINT",LP),process.on("SIGTERM",NP),process.on("exit",BP),Wm=!0)}function UP(){Wm&&(process.removeListener("SIGINT",LP),process.removeListener("SIGTERM",NP),process.removeListener("exit",BP),Wm=!1)}async function O5(e){return or!==null?or:(xi!==null||(xi=(async()=>{let{PlaywrightProvider:t}=await Promise.resolve().then(()=>(FP(),DP)),n=hP(e),r=new t(n);return M5(),or=r,xi=null,r})()),xi)}async function hv(){if(or===null)return;let e=or;or=null,xi=null,UP(),await e.shutdown()}function $5(){return or!==null}function D5(){return or}function F5(){or=null,xi=null,UP()}var or,xi,Wm,Ai=x(()=>{"use strict";Lm();or=null,xi=null,Wm=!1});async function jP(e,t){try{return await iP(e,t)}catch(n){return W("[web/scrape] extraction failed",{url:t,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function H5(e,t){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(Ai(),Ri));return(await n()).render({url:e,timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:t.requestGuard})}async function HP(e,t){let n=t.fetchFn??globalThis.fetch,r=t.renderFn??H5,o=t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{},i=null,s=e,a=null,l=null;try{let d=await Dm(n,e,{headers:j5,signal:t.signal},o);a=d.status,s=d.url||e;let u=d.headers.get("content-type")??"";if(d.ok){if(U5.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 m=await d.text();if(B5.test(u)&&!N5.test(u))return{title:"",markdown:m.trim(),finalUrl:s,usedRender:!1};if(i=await jP(m,s),t.signal.aborted)throw t.signal.reason??new Error("aborted")}}catch(d){if(t.signal.aborted||d instanceof Pn||d instanceof Error&&d.message.startsWith("web_scrape markdown mode received binary"))throw d;l=d}if(!(i===null||i.textLength<200)&&i!==null)return{title:i.title,markdown:i.markdown,finalUrl:s,usedRender:!1};try{await Vc(e,o);let d=await r(e,{timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:m=>Vc(m,o)});d.finalUrl!==e&&/^https?:\/\//i.test(d.finalUrl)&&await Vc(d.finalUrl,o);let u=await jP(d.html,d.finalUrl);if(t.signal.aborted)throw t.signal.reason??new Error("aborted");if(i===null||u.textLength>=i.textLength)return{title:u.title,markdown:u.markdown,finalUrl:d.finalUrl,usedRender:!0}}catch(d){if(t.signal.aborted||d instanceof Pn)throw d;if(i===null){let u=d instanceof Error?d.message:String(d),m=l instanceof Error?l.message:`HTTP ${a??"error"}`,f=new Error(`web_scrape could not retrieve ${e}: fetch failed (${m}) and render failed (${u}).`);throw f.cause=d,f}}if(i!==null)return{title:i.title,markdown:i.markdown,finalUrl:s,usedRender:!1};throw new Error(`web_scrape could not retrieve any content from ${e} (HTTP ${a??"error"}).`)}var N5,B5,U5,j5,WP=x(()=>{"use strict";sP();lv();be();N5=/(text\/html|application\/xhtml\+xml)/i,B5=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,U5=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,j5={"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 G5(e){let t=e.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let i=await t(W5,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json","x-api-key":e.apiKey,"User-Agent":"agent-afk/web_scrape"},body:JSON.stringify({query:n,type:"auto",numResults:Math.min(Math.max(r,1),K5),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!i.ok){let l="";try{let d=await i.text(),u=Ir(d);u&&(l=`: ${u.length>200?u.slice(0,200)+"\u2026":u}`)}catch{}let c=i.statusText?` ${i.statusText}`:"";throw new Error(`Exa Search HTTP ${i.status}${c}${l}`)}let s;try{s=await i.json()}catch(l){throw new Error(`Exa Search response was not JSON: ${l instanceof Error?l.message:String(l)}`)}return(s.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 KP(e){return e.exaApiKey!==void 0&&e.exaApiKey.trim()!==""?G5({apiKey:e.exaApiKey,fetchFn:e.fetchFn}):{error:'web_scrape search mode requires a search backend. Set EXA_API_KEY (free tier at https://exa.ai) to enable it. Use mode: "markdown" to read a known URL, or mode: "raw" for a direct fetch.'}}function GP(e,t){if(t.length===0)return`# Search results for "${e}"
|
|
879
879
|
|
|
880
880
|
(no results)`;let n=[`# Search results for "${e}"`,""];return t.forEach((r,o)=>{n.push(`## ${o+1}. ${r.title}`),r.url&&n.push(r.url),r.description&&n.push(r.description),n.push("")}),n.join(`
|
|
881
881
|
`).trimEnd()}var W5,K5,qP=x(()=>{"use strict";ho();W5="https://api.exa.ai/search",K5=10});function Km(e){if(e instanceof Error&&e.name==="TimeoutError")return"timeout";let t=e instanceof Error?e.message:String(e);return/Timeout\s+\d+\s*ms exceeded/i.test(t)?"timeout":void 0}var Ci=x(()=>{"use strict";Nm()});function X5(e){if(!e||typeof e!="object")return{error:"Invalid input: expected an object"};let t=e,n=t.mode??"markdown";if(n!=="markdown"&&n!=="raw"&&n!=="search")return{error:`Invalid input: mode must be one of "markdown", "raw", "search" (got ${JSON.stringify(n)})`};let r=n,o,i;if(r==="search"){if(typeof t.query!="string"||t.query.length===0)return{error:'Invalid input: search mode requires a non-empty "query" string'};i=t.query}else{if(typeof t.url!="string"||t.url.length===0)return{error:`Invalid input: ${r} mode requires a non-empty "url" string`};let l;try{l=new URL(t.url)}catch{return{error:`Invalid input: "${t.url}" is not a valid absolute URL`}}if(l.protocol!=="http:"&&l.protocol!=="https:")return{error:`Invalid input: protocol "${l.protocol}" not supported (http/https only)`};o=l.toString()}let s=q5;if(t.timeout_ms!==void 0){if(typeof t.timeout_ms!="number"||!Number.isFinite(t.timeout_ms)||t.timeout_ms<=0)return{error:"Invalid input: timeout_ms must be a positive finite number"};s=Math.min(t.timeout_ms,z5)}let a=J5;if(t.max_bytes!==void 0){if(typeof t.max_bytes!="number"||!Number.isFinite(t.max_bytes)||t.max_bytes<=0)return{error:"Invalid input: max_bytes must be a positive finite number"};a=Math.min(t.max_bytes,Y5)}return{mode:r,url:o,query:i,timeoutMs:s,maxBytes:a}}function yv(e,t){return Buffer.byteLength(e,"utf8")<=t?{content:e,truncated:!1}:{content:Cr(e,t),truncated:!0}}function Q5(e={}){let t=e.fetchFn??globalThis.fetch,n=e.env??process.env,r=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{};return async(o,i)=>{if(typeof t!="function")return{content:"web_scrape unavailable: global fetch() is not present in this runtime (agent-afk requires Node 20+).",isError:!0};let s=X5(o);if("error"in s)return{content:s.error,isError:!0};if(i.aborted){let u=i.reason;return{content:`web_scrape aborted: ${u instanceof Error?u.message:String(u??"aborted")}`,isError:!0}}let a=new AbortController,l=()=>{a.abort(i.reason)},c,d=()=>{let u=a.signal.reason;return u instanceof Error?u.message:String(u??"aborted")};try{if(i.addEventListener("abort",l,{once:!0}),c=setTimeout(()=>{a.abort(new Error(`web_scrape timeout after ${s.timeoutMs}ms`))},s.timeoutMs),s.url!==void 0){let m=await av(s.url,r);if(a.signal.aborted)return{content:`web_scrape aborted: ${d()}`,isError:!0};if(!m.allowed)return{content:`web_scrape blocked: ${m.reason}`,isError:!0}}if(s.mode==="raw"){let m;try{let h={method:"GET",headers:{"User-Agent":"agent-afk/web_scrape",Accept:"*/*"},signal:a.signal};m=await Dm(t,s.url,h,r)}catch(h){return a.signal.aborted?{content:`web_scrape aborted: ${d()}`,isError:!0}:h instanceof Pn?{content:`web_scrape blocked: ${h.message}`,isError:!0}:{content:`web_scrape network error: ${h instanceof Error?h.message:String(h)}`,isError:!0}}if(!m.ok)return{content:`web_scrape HTTP ${m.status} ${m.statusText||""}`.trimEnd()+` for ${s.url}`,isError:!0};let f;try{f=await m.text()}catch(h){return{content:`web_scrape read error: ${h instanceof Error?h.message:String(h)}`,isError:!0}}let g=yv(f,s.maxBytes);return{content:g.content,...g.truncated?{truncated:!0}:{}}}if(s.mode==="markdown")try{let m=await HP(s.url,{fetchFn:t,renderFn:e.renderFn,timeoutMs:s.timeoutMs,signal:a.signal,...e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{}});if(m.markdown.trim().length===0)return{content:`web_scrape extracted no readable content from ${s.url}.`,isError:!0};let f=yv(m.markdown,s.maxBytes);return{content:f.content,...f.truncated?{truncated:!0}:{}}}catch(m){if(a.signal.aborted)return{content:`web_scrape aborted: ${d()}`,isError:!0};if(m instanceof Pn)return{content:`web_scrape blocked: ${m.message}`,isError:!0};let f=m instanceof Error?m.message:String(m),g=Ut(m)&&!cv(f)?` (the render fallback needs the optional Playwright browser \u2014 run \`${Xc()}\`)`:"";return{content:`web_scrape markdown error: ${f}${g}`,isError:!0}}let u=KP({exaApiKey:n.EXA_API_KEY,fetchFn:t});if("error"in u)return{content:u.error,isError:!0};try{let m=await u.search(s.query,{limit:V5,timeoutMs:s.timeoutMs,signal:a.signal}),f=yv(GP(s.query,m),s.maxBytes);return{content:f.content,...f.truncated?{truncated:!0}:{}}}catch(m){return a.signal.aborted?{content:`web_scrape aborted: ${d()}`,isError:!0}:{content:`web_scrape search error (${u.name}): ${m instanceof Error?m.message:String(m)}`,isError:!0}}}finally{c!==void 0&&clearTimeout(c),i.removeEventListener("abort",l)}}}var q5,z5,J5,Y5,V5,zP,JP=x(()=>{"use strict";WP();qP();lv();yi();Ci();q5=3e4,z5=12e4,J5=1e5,Y5=1e6,V5=10;zP=Q5()});import{existsSync as VP,mkdirSync as Z5,readFileSync as e3,renameSync as t3,unlinkSync as n3,writeFileSync as r3}from"node:fs";import{dirname as YP,join as o3}from"node:path";import{randomBytes as i3}from"node:crypto";function mn(e){let t=e??rw();if(!VP(t))return[];try{let n=e3(t,"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 ${t}: ${r}`),[]}}function _i(e,t){let n=t??rw();Z5(YP(n),{recursive:!0});let r=o3(YP(n),`.schedules.json.${process.pid}.${i3(4).toString("hex")}.tmp`),o=JSON.stringify(e,null,2);try{r3(r,o,"utf-8"),t3(r,n)}catch(i){try{VP(r)&&n3(r)}catch{}throw i}}function Gm(e,t){let n=mn(t),r=n.map(l=>l.id),o=s3(e.name),i=a3(o,r),s=new Date().toISOString(),a={...e,notifyOn:e.notifyOn??"failure",id:i,createdAt:s,updatedAt:s};return n.push(a),_i(n,t),a}function qm(e,t){let n=mn(t),r=n.length,o=n.filter(i=>i.id!==e);return o.length===r?!1:(_i(o,t),!0)}function Zc(e,t){return mn(t).find(n=>n.id===e)}function s3(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"")}function a3(e,t){if(!t.includes(e))return e;let n=2;for(;t.includes(`${e}-${n}`);)n+=1;return`${e}-${n}`}function XP(e){return{taskId:e.id,command:e.command,trigger:e.trigger??"cron",...e.cron!==void 0?{cronExpression:e.cron}:{},...e.notifyOn!==void 0?{notifyOn:e.notifyOn}:{},...e.notifyChat!==void 0?{notifyChat:e.notifyChat}:{}}}var zm=x(()=>{"use strict";z()});import{existsSync as l3,readFileSync as c3}from"node:fs";import{join as d3}from"node:path";async function Mn(e,t,n){let r;try{let o=d3(fp("default"),"port");if(!l3(o))return{synced:!1,detail:"daemon-not-detected (no port file)"};let i=c3(o,"utf-8").trim();if(r=parseInt(i,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}${t}`,{method:e,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"}:e==="POST"&&o.status===409?{synced:!0,detail:"already-registered"}:e==="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 wo,bv=x(()=>{"use strict";z();wo="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 u3}from"node:fs";import{readFile as p3}from"node:fs/promises";var QP,ZP,eM,tM,nM=x(()=>{"use strict";zm();z();bv();QP=async(e,t)=>{if(!e||typeof e!="object")return{content:"Invalid input: expected object",isError:!0};let n=e;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 i=Gm({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}),s=i.enabled?await Mn("POST","/tasks",{taskId:i.id,command:i.command,cron:i.cron,trigger:i.trigger,notifyOn:i.notifyOn,...i.notifyChat!==void 0?{notifyChat:i.notifyChat}:{}}):await Mn("DELETE",`/tasks/${i.id}`);return{content:JSON.stringify({id:i.id,name:i.name,cron:i.cron,enabled:i.enabled,daemonSynced:s.synced,syncDetail:s.detail,...s.synced?{}:{syncNote:wo}})}},ZP=async(e,t)=>{let n=mn();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})))}},eM=async(e,t)=>{if(!e||typeof e!="object")return{content:"Invalid input: expected object",isError:!0};let n=e;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,i=Gn();if(!u3(i))return{content:JSON.stringify([])};let s;try{let c=await p3(i);s=(c.length>1048576?c.subarray(c.length-1048576):c).toString("utf-8")}catch{return{content:JSON.stringify([])}}let a=s.split(`
|
|
@@ -1266,7 +1266,7 @@ ${w.map(A=>`> - ${A}`).join(`
|
|
|
1266
1266
|
|
|
1267
1267
|
${n}${u}
|
|
1268
1268
|
|
|
1269
|
-
Choose how to handle this and future requests for this path.`,f=await nt.route({serverName:"agent-afk",message:m,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 y=f.action==="cancel"?"cancel":"block";return console.error(`[path-approval] surface=${a} tool=${t} path=${n} outcome=${y}`),{decision:"block",reason:f.action==="cancel"?`User cancelled the access prompt for ${n}`:`User denied access to ${n}`}}let g=String(f.content?.choice??"").toLowerCase(),h=NT(o,n);switch(g){case"once":return o==="write"?i.addWriteRoot(n,"tool"):i.addReadRoot(n,"tool"),s.onceApproved.set(h,{resolvedPath:n,mode:o,capturedCwd:r}),console.error(`[path-approval] surface=${a} tool=${t} path=${n} outcome=once`),{};case"session":return o==="write"?i.addWriteRoot(n,"tool"):i.addReadRoot(n,"tool"),s.sessionApproved.add(h),console.error(`[path-approval] surface=${a} tool=${t} path=${n} outcome=session`),{};case"persist":o==="write"?i.addWriteRoot(n,"tool"):i.addReadRoot(n,"tool"),s.sessionApproved.add(h),console.error(`[path-approval] surface=${a} tool=${t} path=${n} outcome=persist`);try{xL({path:n,mode:o,decision:"allow",source:a==="telegram"?"elicit:telegram":a==="repl"?"elicit:repl":"elicit:unknown",reason:`Approved via ${a} prompt for ${t}`})}catch(y){console.error(`path-approval: failed to persist grant for ${n}:`,y instanceof Error?y.message:String(y))}return{};default:return console.error(`[path-approval] surface=${a} tool=${t} path=${n} outcome=deny`),{decision:"block",reason:`User denied access to ${n}`}}}Pr();G();import{homedir as $L}from"os";import Ki from"path";Pr();z();qc();import BT from"path";function UT(){try{return BT.resolve(he())}catch(e){rr(e);return}}function ML(e){return bo.flatMap(t=>{if(!t.startsWith(".afk/"))return[];let n=BT.join(e,t.slice(5));return Bt(n).denied?[]:[n,`$AFK_HOME/${t.slice(5)}`]})}function OL(){let e=UT();return e===void 0?[]:[BT.join(e,"config")]}var tne=/\b(python|python3|node|ruby|perl|osascript|sh|bash|zsh|fish|lua)\s+-[cCeE](\s|$)/,nne=/\.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 DL(e){return t=>{if(t.event!=="PreToolUse")return{};if(t.toolName!=="bash")return{};let n=t.input,r=typeof n?.command=="string"?n.command:"";if(!r)return{};let o=t.grantManager??e.getGrantManager(),i=o!==void 0,s=$L(),a=UT(),l=lne(rne(r,s,a),s,a),c=o?mne(o.getGrants()):[];if(!e.disableInterpreterGuard&&(i||e.forceInterpreterGuard===!0)&&tne.test(r)&&cne(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 rne(e,t,n){return(n===void 0?e:e.replace(/\$\{AFK_HOME\}|\$AFK_HOME\b/g,n)).replace(/\$\{HOME\}|\$HOME\b/g,t).replace(/(^|[\s/=:])~(?=$|[/\s])/g,`$1${t}`).replace(one,o=>Ki.posix.normalize(o))}var one=/\/[^\s'"`;|&()<>]*/g,ine="<allowlisted-file>";function sne(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function ane(e,t){let n=bo.flatMap(o=>Bt(Ki.join(e,o)).denied?[]:[Ki.join(e,o),`~/${o}`,`$HOME/${o}`]);if(t===void 0)return n;let r=ML(t);return[...new Set([...n,...r])]}function lne(e,t,n){let r=e;for(let o of ane(t,n)){let i=new RegExp(`${sne(o)}(?![\\w./\\\\*?\\[\\]{}-])`,"g");r=r.replace(i,ine)}return r}function cne(e,t){return t.some(n=>e.includes(n))?!0:nne.test(e)}function dne(){let e=$L();return pne([Ki.join(e,"Library","Application Support"),Ki.join(e,".password-store"),Ki.join(e,".config","gh"),...JS])}function une(){return YS(v.AFK_READ_DENYLIST)}function pne(e){let t=[];for(let n of e)t.push(n),n.startsWith("/etc/")?t.push(`/private${n}`):n.startsWith("/private/etc/")&&t.push(n.slice(8));return t}function mne(e){let t=[...new Set([...dne(),...VS(),...une(),...OL()])],n=new Set([...e.resolveBase!==void 0?[e.resolveBase]:[],...e.readRoots,...e.writeRoots]);return t.filter(r=>{for(let o of n){let i=Ki.relative(o,r);if(i===""||!i.startsWith(".."))return!1}return!0})}z();Fr();Bc();import{existsSync as Yg,readFileSync as fne}from"node:fs";import{join as HT}from"node:path";var gne=3e4;function FL(e){if(e===void 0||e==="*")return()=>!0;let t=/^\/(.+)\/([gimsuy]*)$/.exec(e);if(t!==null){let n=t[1],r=t[2];try{let o=r.replace(/[gy]/g,""),i=new RegExp(n,o);return s=>i.test(s)}catch{}}return n=>n===e}function hne(e){if(e===null||typeof e!="object"||Array.isArray(e))return null;let t=e;if(t.type!=="command"||typeof t.command!="string"||t.command.length===0)return null;let n=typeof t.timeout_ms=="number"&&t.timeout_ms>0?t.timeout_ms:gne,r=Math.min(n,fi);return{type:"command",command:t.command,timeoutMs:r}}function jT(e,t,n){let r=[],o=[],i={};if(!Yg(e))return{hooks:i,enableShellHooks:!1,allowProjectHooks:!1,enablePluginHooks:!1,sources:o,warnings:r};o.push(e);let s;try{s=JSON.parse(fne(e,"utf-8"))}catch(g){let h=g instanceof Error?g.message:String(g);return r.push(`hooks config at ${e}: parse error \u2014 ${h}`),{hooks:i,enableShellHooks:!1,allowProjectHooks:!1,enablePluginHooks:!1,sources:o,warnings:r}}if(s===null||typeof s!="object"||Array.isArray(s))return r.push(`hooks config at ${e}: top-level must be an object`),{hooks:i,enableShellHooks:!1,allowProjectHooks:!1,enablePluginHooks:!1,sources:o,warnings:r};let a=s,l=a.enableShellHooks===!0,c=a.allowProjectHooks===!0,d=a.enablePluginHooks===!0,u=a.hooks;if(u==null)return{hooks:i,enableShellHooks:l,allowProjectHooks:c,enablePluginHooks:d,sources:o,warnings:r};if(typeof u!="object"||Array.isArray(u))return r.push(`hooks config at ${e}: "hooks" must be an object`),{hooks:i,enableShellHooks:l,allowProjectHooks:c,enablePluginHooks:d,sources:o,warnings:r};let m=u,f=["SessionStart","SessionEnd","SubagentStart","SubagentStop","PreToolUse","PostToolUse","PreCompact","PostToolUseFailure","Stop","UserPromptSubmit"];for(let g of f){let h=m[g];if(h===void 0)continue;if(!Array.isArray(h)){r.push(`hooks config at ${e}: hooks.${g} must be an array`);continue}let y=[];for(let b=0;b<h.length;b++){let w=h[b];if(w===null||typeof w!="object"||Array.isArray(w)){r.push(`hooks config at ${e}: hooks.${g}[${b}] must be an object \u2014 skipping`);continue}let S=w,k=typeof S.matcher=="string"?S.matcher:void 0;if(!Array.isArray(S.hooks)){r.push(`hooks config at ${e}: hooks.${g}[${b}].hooks must be an array \u2014 skipping`);continue}let T=S.hooks,A=[];for(let O=0;O<T.length;O++){let E=T[O],D=hne(E);if(D===null){let C=E!==null&&typeof E=="object"&&!Array.isArray(E)?E.type:void 0,M=typeof C=="string"&&C!=="command"?`has unsupported hook type "${C}" (only "command" is honored)`:'is malformed (must have type="command" and non-empty command)';r.push(`hooks config at ${e}: hooks.${g}[${b}].hooks[${O}] ${M} \u2014 skipping`);continue}n!==void 0&&(D.pluginRoot=n),A.push(D)}A.length>0&&y.push({...k!==void 0?{matcher:k}:{},hooks:A,tier:t})}y.length>0&&(i[g]=y)}return{hooks:i,enableShellHooks:l,allowProjectHooks:c,enablePluginHooks:d,sources:o,warnings:r}}function yne(e=Ge()){if(!Yg(e))return[];let t=[];for(let n of Bn(e)){let r=HT(n.path,"hooks","hooks.json");Yg(r)&&t.push({path:r,pluginRoot:n.path})}return t}function Ja(e={}){let t=e.cwd??process.cwd(),n=[],r=[],o={},i=!1,s=!1,a=!1,l=[{path:Kt(),tier:"user-global"},{path:aw(),tier:"user-global"},{path:HT(t,"afk.config.json"),tier:"project-local"},{path:xA(t),tier:"project-local"}],c=new Set,d=l.filter(f=>c.has(f.path)?!1:(c.add(f.path),!0));try{let f=HT(he(),"settings.json");!c.has(f)&&Yg(f)&&r.push(`found ${f} but AFK does not read settings from the AFK-home root; user-global hooks/settings belong in ${aw()} \u2014 the root file is ignored`)}catch{}for(let f of d){if(f.tier!=="user-global")continue;let g=jT(f.path,f.tier);g.enableShellHooks&&(i=!0),g.allowProjectHooks&&(s=!0),g.enablePluginHooks&&(a=!0)}let u=["SessionStart","SessionEnd","SubagentStart","SubagentStop","PreToolUse","PostToolUse","PreCompact","PostToolUseFailure","Stop","UserPromptSubmit"];for(let f of d){let g=jT(f.path,f.tier);for(let h of g.sources)n.includes(h)||n.push(h);for(let h of g.warnings)r.push(h);if(!(f.tier==="project-local"&&!s))for(let h of u){let y=g.hooks[h];if(y===void 0||y.length===0)continue;let b=o[h];b===void 0?o[h]=[...y]:o[h]=[...b,...y]}}let m=yne(e.pluginsDir);if(m.length>0&&!a&&r.push(`found ${m.length} plugin hooks.json file(s) but plugin hooks are disabled; set "enablePluginHooks": true in ${Kt()} to run them`),a)for(let{path:f,pluginRoot:g}of m){let h=jT(f,"plugin",g);for(let y of h.sources)n.includes(y)||n.push(y);for(let y of h.warnings)r.push(y);for(let y of u){let b=h.hooks[y];if(b===void 0||b.length===0)continue;let w=o[y];w===void 0?o[y]=[...b]:o[y]=[...w,...b]}}return{hooks:o,userGlobalEnabled:i,allowProjectHooks:s,pluginHooksEnabled:a,sources:n,warnings:r}}import{spawn as bne}from"node:child_process";import{homedir as wne}from"node:os";import{StringDecoder as LL}from"node:string_decoder";async function NL(e){let{context:t,agentCwd:n,sessionId:r,timeoutMs:o}=e,i=e.command.replace(/^~\//,wne()+"/"),s={session_id:r,hook_event_name:t.event,cwd:n};(t.event==="PreToolUse"||t.event==="PostToolUse"||t.event==="PostToolUseFailure")&&(s.tool_name=t.toolName),t.event==="PreToolUse"&&(s.tool_input=t.input),t.event==="PostToolUse"&&t.output!==void 0&&(s.tool_output=typeof t.output=="string"?t.output:JSON.stringify(t.output)),t.event==="PostToolUseFailure"&&(s.error=t.error),t.event==="PreCompact"&&(s.trigger=t.trigger??null),t.event==="UserPromptSubmit"&&(s.prompt=t.prompt),s.transcript_path=null;let a=JSON.stringify(s),l=t.event==="PreToolUse"||t.event==="PostToolUse"||t.event==="PostToolUseFailure"?t.toolName:"",c=["PATH","HOME","SHELL","LANG","TERM","TMPDIR","TMP","TEMP","USER","LOGNAME"],d={};for(let m of c){let f=process.env[m];f!==void 0&&(d[m]=f)}let u=/_(KEY|TOKEN|SECRET|PASSWORD|PASSWD|CREDENTIAL|CREDENTIALS)$/i;for(let[m,f]of Object.entries(process.env))!m.startsWith("AFK_")||f===void 0||u.test(m)||(d[m]=f);return d.AFK_PROJECT_DIR=n,d.AFK_SESSION_ID=r??"",d.AFK_HOOK_EVENT=t.event,d.AFK_TOOL_NAME=l,e.pluginRoot!==void 0&&(d.CLAUDE_PLUGIN_ROOT=e.pluginRoot,d.CLAUDE_PROJECT_DIR=n),new Promise(m=>{let f=!1;function g(E){f||(f=!0,m(E))}let h=bne("sh",["-c",i],{stdio:["pipe","pipe","pipe"],cwd:n,env:d,detached:!0});h.unref();let y=64e3,b="",w="",S=0,k=0,T=new LL("utf8"),A=new LL("utf8");h.stdout.on("data",E=>{if(S>=y)return;let D=y-S,C=E.length<=D?E:E.subarray(0,D);S+=C.length,b+=T.write(C)}),h.stderr.on("data",E=>{if(k>=y)return;let D=y-k,C=E.length<=D?E:E.subarray(0,D);k+=C.length,w+=A.write(C)});let O=setTimeout(()=>{if(!f){if(h.pid!==void 0)try{process.kill(-h.pid,"SIGKILL")}catch{}console.warn(`[hooks] command timed out after ${o}ms: ${i}`),g({decision:{}})}},o);O.unref(),h.stdin.on("error",()=>{});try{h.stdin.write(a),h.stdin.end()}catch{}h.on("close",E=>{if(!f){if(clearTimeout(O),b+=T.end(),w+=A.end(),E===0){let D=Sne(b);g({decision:D});return}if(E===2){let D=w.trim().slice(0,500)||"hook blocked operation";g({decision:{decision:"block",reason:D}});return}console.warn(`[hooks] command exited with code ${String(E)}: ${i}${w.trim()?`
|
|
1269
|
+
Choose how to handle this and future requests for this path.`,f=await nt.route({serverName:"agent-afk",message:m,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 y=f.action==="cancel"?"cancel":"block";return console.error(`[path-approval] surface=${a} tool=${t} path=${n} outcome=${y}`),{decision:"block",reason:f.action==="cancel"?`User cancelled the access prompt for ${n}`:`User denied access to ${n}`}}let g=String(f.content?.choice??"").toLowerCase(),h=NT(o,n);switch(g){case"once":return o==="write"?i.addWriteRoot(n,"tool"):i.addReadRoot(n,"tool"),s.onceApproved.set(h,{resolvedPath:n,mode:o,capturedCwd:r}),console.error(`[path-approval] surface=${a} tool=${t} path=${n} outcome=once`),{};case"session":return o==="write"?i.addWriteRoot(n,"tool"):i.addReadRoot(n,"tool"),s.sessionApproved.add(h),console.error(`[path-approval] surface=${a} tool=${t} path=${n} outcome=session`),{};case"persist":o==="write"?i.addWriteRoot(n,"tool"):i.addReadRoot(n,"tool"),s.sessionApproved.add(h),console.error(`[path-approval] surface=${a} tool=${t} path=${n} outcome=persist`);try{xL({path:n,mode:o,decision:"allow",source:a==="telegram"?"elicit:telegram":a==="repl"?"elicit:repl":"elicit:unknown",reason:`Approved via ${a} prompt for ${t}`})}catch(y){console.error(`path-approval: failed to persist grant for ${n}:`,y instanceof Error?y.message:String(y))}return{};default:return console.error(`[path-approval] surface=${a} tool=${t} path=${n} outcome=deny`),{decision:"block",reason:`User denied access to ${n}`}}}Pr();G();import{homedir as $L}from"os";import Ki from"path";Pr();z();qc();import BT from"path";function UT(){try{return BT.resolve(he())}catch(e){rr(e);return}}function ML(e){return bo.flatMap(t=>{if(!t.startsWith(".afk/"))return[];let n=BT.join(e,t.slice(5));return Bt(n).denied?[]:[n,`$AFK_HOME/${t.slice(5)}`]})}function OL(){let e=UT();return e===void 0?[]:[BT.join(e,"config")]}var tne=/\b(python|python3|node|ruby|perl|osascript|sh|bash|zsh|fish|lua)\s+-[cCeE](\s|$)/,nne=/\.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 DL(e){return t=>{if(t.event!=="PreToolUse")return{};if(t.toolName!=="bash")return{};let n=t.input,r=typeof n?.command=="string"?n.command:"";if(!r)return{};let o=t.grantManager??e.getGrantManager(),i=o!==void 0,s=$L(),a=UT(),l=lne(rne(r,s,a),s,a),c=o?mne(o.getGrants()):[];if(!e.disableInterpreterGuard&&(i||e.forceInterpreterGuard===!0)&&tne.test(r)&&cne(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 rne(e,t,n){return(n===void 0?e:e.replace(/\$\{AFK_HOME\}|\$AFK_HOME\b/g,n)).replace(/\$\{HOME\}|\$HOME\b/g,t).replace(/(^|[\s/=:])~(?=$|[/\s])/g,`$1${t}`).replace(one,o=>Ki.posix.normalize(o))}var one=/\/[^\s'"`;|&()<>]*/g,ine="<allowlisted-file>";function sne(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function ane(e,t){let n=bo.flatMap(o=>Bt(Ki.join(e,o)).denied?[]:[Ki.join(e,o),`~/${o}`,`$HOME/${o}`]);if(t===void 0)return n;let r=ML(t);return[...new Set([...n,...r])]}function lne(e,t,n){let r=e;for(let o of ane(t,n)){let i=new RegExp(`${sne(o)}(?![\\w./\\\\*?\\[\\]{}-])(?!['"\`][\\w./\\\\*?\\[\\]{}-])`,"g");r=r.replace(i,ine)}return r}function cne(e,t){return t.some(n=>e.includes(n))?!0:nne.test(e)}function dne(){let e=$L();return pne([Ki.join(e,"Library","Application Support"),Ki.join(e,".password-store"),Ki.join(e,".config","gh"),...JS])}function une(){return YS(v.AFK_READ_DENYLIST)}function pne(e){let t=[];for(let n of e)t.push(n),n.startsWith("/etc/")?t.push(`/private${n}`):n.startsWith("/private/etc/")&&t.push(n.slice(8));return t}function mne(e){let t=[...new Set([...dne(),...VS(),...une(),...OL()])],n=new Set([...e.resolveBase!==void 0?[e.resolveBase]:[],...e.readRoots,...e.writeRoots]);return t.filter(r=>{for(let o of n){let i=Ki.relative(o,r);if(i===""||!i.startsWith(".."))return!1}return!0})}z();Fr();Bc();import{existsSync as Yg,readFileSync as fne}from"node:fs";import{join as HT}from"node:path";var gne=3e4;function FL(e){if(e===void 0||e==="*")return()=>!0;let t=/^\/(.+)\/([gimsuy]*)$/.exec(e);if(t!==null){let n=t[1],r=t[2];try{let o=r.replace(/[gy]/g,""),i=new RegExp(n,o);return s=>i.test(s)}catch{}}return n=>n===e}function hne(e){if(e===null||typeof e!="object"||Array.isArray(e))return null;let t=e;if(t.type!=="command"||typeof t.command!="string"||t.command.length===0)return null;let n=typeof t.timeout_ms=="number"&&t.timeout_ms>0?t.timeout_ms:gne,r=Math.min(n,fi);return{type:"command",command:t.command,timeoutMs:r}}function jT(e,t,n){let r=[],o=[],i={};if(!Yg(e))return{hooks:i,enableShellHooks:!1,allowProjectHooks:!1,enablePluginHooks:!1,sources:o,warnings:r};o.push(e);let s;try{s=JSON.parse(fne(e,"utf-8"))}catch(g){let h=g instanceof Error?g.message:String(g);return r.push(`hooks config at ${e}: parse error \u2014 ${h}`),{hooks:i,enableShellHooks:!1,allowProjectHooks:!1,enablePluginHooks:!1,sources:o,warnings:r}}if(s===null||typeof s!="object"||Array.isArray(s))return r.push(`hooks config at ${e}: top-level must be an object`),{hooks:i,enableShellHooks:!1,allowProjectHooks:!1,enablePluginHooks:!1,sources:o,warnings:r};let a=s,l=a.enableShellHooks===!0,c=a.allowProjectHooks===!0,d=a.enablePluginHooks===!0,u=a.hooks;if(u==null)return{hooks:i,enableShellHooks:l,allowProjectHooks:c,enablePluginHooks:d,sources:o,warnings:r};if(typeof u!="object"||Array.isArray(u))return r.push(`hooks config at ${e}: "hooks" must be an object`),{hooks:i,enableShellHooks:l,allowProjectHooks:c,enablePluginHooks:d,sources:o,warnings:r};let m=u,f=["SessionStart","SessionEnd","SubagentStart","SubagentStop","PreToolUse","PostToolUse","PreCompact","PostToolUseFailure","Stop","UserPromptSubmit"];for(let g of f){let h=m[g];if(h===void 0)continue;if(!Array.isArray(h)){r.push(`hooks config at ${e}: hooks.${g} must be an array`);continue}let y=[];for(let b=0;b<h.length;b++){let w=h[b];if(w===null||typeof w!="object"||Array.isArray(w)){r.push(`hooks config at ${e}: hooks.${g}[${b}] must be an object \u2014 skipping`);continue}let S=w,k=typeof S.matcher=="string"?S.matcher:void 0;if(!Array.isArray(S.hooks)){r.push(`hooks config at ${e}: hooks.${g}[${b}].hooks must be an array \u2014 skipping`);continue}let T=S.hooks,A=[];for(let O=0;O<T.length;O++){let E=T[O],D=hne(E);if(D===null){let C=E!==null&&typeof E=="object"&&!Array.isArray(E)?E.type:void 0,M=typeof C=="string"&&C!=="command"?`has unsupported hook type "${C}" (only "command" is honored)`:'is malformed (must have type="command" and non-empty command)';r.push(`hooks config at ${e}: hooks.${g}[${b}].hooks[${O}] ${M} \u2014 skipping`);continue}n!==void 0&&(D.pluginRoot=n),A.push(D)}A.length>0&&y.push({...k!==void 0?{matcher:k}:{},hooks:A,tier:t})}y.length>0&&(i[g]=y)}return{hooks:i,enableShellHooks:l,allowProjectHooks:c,enablePluginHooks:d,sources:o,warnings:r}}function yne(e=Ge()){if(!Yg(e))return[];let t=[];for(let n of Bn(e)){let r=HT(n.path,"hooks","hooks.json");Yg(r)&&t.push({path:r,pluginRoot:n.path})}return t}function Ja(e={}){let t=e.cwd??process.cwd(),n=[],r=[],o={},i=!1,s=!1,a=!1,l=[{path:Kt(),tier:"user-global"},{path:aw(),tier:"user-global"},{path:HT(t,"afk.config.json"),tier:"project-local"},{path:xA(t),tier:"project-local"}],c=new Set,d=l.filter(f=>c.has(f.path)?!1:(c.add(f.path),!0));try{let f=HT(he(),"settings.json");!c.has(f)&&Yg(f)&&r.push(`found ${f} but AFK does not read settings from the AFK-home root; user-global hooks/settings belong in ${aw()} \u2014 the root file is ignored`)}catch{}for(let f of d){if(f.tier!=="user-global")continue;let g=jT(f.path,f.tier);g.enableShellHooks&&(i=!0),g.allowProjectHooks&&(s=!0),g.enablePluginHooks&&(a=!0)}let u=["SessionStart","SessionEnd","SubagentStart","SubagentStop","PreToolUse","PostToolUse","PreCompact","PostToolUseFailure","Stop","UserPromptSubmit"];for(let f of d){let g=jT(f.path,f.tier);for(let h of g.sources)n.includes(h)||n.push(h);for(let h of g.warnings)r.push(h);if(!(f.tier==="project-local"&&!s))for(let h of u){let y=g.hooks[h];if(y===void 0||y.length===0)continue;let b=o[h];b===void 0?o[h]=[...y]:o[h]=[...b,...y]}}let m=yne(e.pluginsDir);if(m.length>0&&!a&&r.push(`found ${m.length} plugin hooks.json file(s) but plugin hooks are disabled; set "enablePluginHooks": true in ${Kt()} to run them`),a)for(let{path:f,pluginRoot:g}of m){let h=jT(f,"plugin",g);for(let y of h.sources)n.includes(y)||n.push(y);for(let y of h.warnings)r.push(y);for(let y of u){let b=h.hooks[y];if(b===void 0||b.length===0)continue;let w=o[y];w===void 0?o[y]=[...b]:o[y]=[...w,...b]}}return{hooks:o,userGlobalEnabled:i,allowProjectHooks:s,pluginHooksEnabled:a,sources:n,warnings:r}}import{spawn as bne}from"node:child_process";import{homedir as wne}from"node:os";import{StringDecoder as LL}from"node:string_decoder";async function NL(e){let{context:t,agentCwd:n,sessionId:r,timeoutMs:o}=e,i=e.command.replace(/^~\//,wne()+"/"),s={session_id:r,hook_event_name:t.event,cwd:n};(t.event==="PreToolUse"||t.event==="PostToolUse"||t.event==="PostToolUseFailure")&&(s.tool_name=t.toolName),t.event==="PreToolUse"&&(s.tool_input=t.input),t.event==="PostToolUse"&&t.output!==void 0&&(s.tool_output=typeof t.output=="string"?t.output:JSON.stringify(t.output)),t.event==="PostToolUseFailure"&&(s.error=t.error),t.event==="PreCompact"&&(s.trigger=t.trigger??null),t.event==="UserPromptSubmit"&&(s.prompt=t.prompt),s.transcript_path=null;let a=JSON.stringify(s),l=t.event==="PreToolUse"||t.event==="PostToolUse"||t.event==="PostToolUseFailure"?t.toolName:"",c=["PATH","HOME","SHELL","LANG","TERM","TMPDIR","TMP","TEMP","USER","LOGNAME"],d={};for(let m of c){let f=process.env[m];f!==void 0&&(d[m]=f)}let u=/_(KEY|TOKEN|SECRET|PASSWORD|PASSWD|CREDENTIAL|CREDENTIALS)$/i;for(let[m,f]of Object.entries(process.env))!m.startsWith("AFK_")||f===void 0||u.test(m)||(d[m]=f);return d.AFK_PROJECT_DIR=n,d.AFK_SESSION_ID=r??"",d.AFK_HOOK_EVENT=t.event,d.AFK_TOOL_NAME=l,e.pluginRoot!==void 0&&(d.CLAUDE_PLUGIN_ROOT=e.pluginRoot,d.CLAUDE_PROJECT_DIR=n),new Promise(m=>{let f=!1;function g(E){f||(f=!0,m(E))}let h=bne("sh",["-c",i],{stdio:["pipe","pipe","pipe"],cwd:n,env:d,detached:!0});h.unref();let y=64e3,b="",w="",S=0,k=0,T=new LL("utf8"),A=new LL("utf8");h.stdout.on("data",E=>{if(S>=y)return;let D=y-S,C=E.length<=D?E:E.subarray(0,D);S+=C.length,b+=T.write(C)}),h.stderr.on("data",E=>{if(k>=y)return;let D=y-k,C=E.length<=D?E:E.subarray(0,D);k+=C.length,w+=A.write(C)});let O=setTimeout(()=>{if(!f){if(h.pid!==void 0)try{process.kill(-h.pid,"SIGKILL")}catch{}console.warn(`[hooks] command timed out after ${o}ms: ${i}`),g({decision:{}})}},o);O.unref(),h.stdin.on("error",()=>{});try{h.stdin.write(a),h.stdin.end()}catch{}h.on("close",E=>{if(!f){if(clearTimeout(O),b+=T.end(),w+=A.end(),E===0){let D=Sne(b);g({decision:D});return}if(E===2){let D=w.trim().slice(0,500)||"hook blocked operation";g({decision:{decision:"block",reason:D}});return}console.warn(`[hooks] command exited with code ${String(E)}: ${i}${w.trim()?`
|
|
1270
1270
|
${w.trim()}`:""}`),g({decision:{}})}}),h.on("error",E=>{f||(clearTimeout(O),console.warn(`[hooks] command error: ${i} \u2014 ${E.message}`),g({decision:{}}))})})}function Sne(e){let t=e.trim();if(!t)return{};let n;try{n=JSON.parse(t)}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 i=r.hookSpecificOutput;if(i!==null&&typeof i=="object"&&!Array.isArray(i)){let s=i;typeof s.additionalContext=="string"&&(o.injectContext=s.additionalContext)}return o}function BL(e,t,n){let r=n.cwd??process.cwd(),o=n.sessionId,i=t.userGlobalEnabled,s=["SessionStart","SessionEnd","SubagentStart","SubagentStop","PreToolUse","PostToolUse","PreCompact","PostToolUseFailure","Stop","UserPromptSubmit"];if(!i){let a=[];for(let l of s){let c=t.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).
|
|
1271
1271
|
Skipped ${a.length} hook(s):
|
|
1272
1272
|
`+a.map(l=>` - ${l}`).join(`
|
|
@@ -1767,7 +1767,7 @@ ${k}
|
|
|
1767
1767
|
${T}`})}return{fileBlocks:l,warnings:c}}async function jW(e,t,n,r,o="summary",i,s){let a=wj(e.text,e.attachments);r.onUserMessage&&await Promise.resolve(r.onUserMessage(a)).catch(()=>{}),r.setInFlight(!0),ml(process.stdout,ru(process.cwd(),!0));let l="",c=0,d=!1,u=!1,m=!1,f=!1,g,h=!1,y=!1,b={abort:null},w=0,S=3e3,k=[],T=new Map,A=e.text.startsWith("/")?e.text.split(/[\s:]/)[0]?.slice(1):void 0,O=()=>{let j=r.subagentControl;j?.hasPromotableForeground()&&j.promoteActiveForeground().then(B=>{for(let K of B)(i??{fn:console.log}).fn(p.dim(` \u2192 subagent backgrounded as ${K.jobId}: ${K.label}`))}).catch(()=>{})},E=r.getCompositor?r.getCompositor():null,D=()=>new Pl({out:Ml(i),thinkingMode:o,...A?{activeSkillName:A}:{},onCancel:()=>{t.interrupt().catch(j=>{ze()&&console.error(" "+p.error("session.interrupt() failed:"),j)})},...r.subagentControl?{onBackground:O}:{},...s?.history?{history:s.history}:{},...s?.autocompleteState?{autocompleteState:s.autocompleteState}:{},...s?.promptText!==void 0?{promptText:s.promptText}:{},...r.scrollRegion?{scrollRegion:r.scrollRegion}:{},...E?{compositor:E}:{},...r.onStageChange?{onStageChange:r.onStageChange}:{}}),C=D(),M=async()=>{if(!m){m=!0;try{await C.dispose()}catch{}}},N=async()=>{await C.arm();let j=C.getCompositor();if(i&&j){let B=j;i.fn=K=>B.commitAbove(K),i.suppressSubagentCompletion=!0}r.setActiveCompositor?.(j),r.setInterruptNotifier?.(B=>C.setInterrupting(B)),r.rearmStatus?.()};try{E?E.commitAbove(""):console.log(),r.setSoftStopHandler&&r.setSoftStopHandler(()=>{h=!0,C.setSoftStopping(!0),t.interrupt().catch(F=>{ze()&&console.error(" "+p.error("soft-stop session.interrupt() failed:"),F)});let I=r.subagentControl;I?.hasActiveForeground()&&I.cancelActiveForeground().catch(F=>{ze()&&console.error(" "+p.error("soft-stop cancelActiveForeground() failed:"),F)})}),r.setPauseInterruptHandler&&r.setPauseInterruptHandler(()=>{y=!0,t.interrupt().catch(I=>{ze()&&console.error(" "+p.error("pause-interrupt session.interrupt() failed:"),I)})}),await N(),r.setBackgroundHandler&&r.subagentControl&&r.setBackgroundHandler(O);let{fileBlocks:j,warnings:B}=UW(e.text,{rootDir:process.cwd()});for(let I of B)(i??{fn:console.log}).fn(p.dim(` @-file: ${I}`));let K=j.length>0||e.attachments.length>0?BW(e.text,e.attachments,void 0,j):e.text,_=t.sendMessageStream(K);if(await ra((I,F)=>{C.process(I,F)},async()=>{for await(let I of _){if(h||y)break;if(I.type==="chunk"&&I.chunk.type==="content"?(l+=I.chunk.content,d=!0):I.type==="message"&&!d&&(l=I.message.content),I.type==="stream_retry"&&(l=l.slice(0,c)),I.type==="chunk"&&I.chunk.type==="tool_use_detail"){let F=I.chunk,P={toolName:F.toolName,toolUseId:F.toolUseId,input:F.toolInput,...F.toolInputRaw!==void 0&&{inputRaw:F.toolInputRaw}};T.set(F.toolUseId,P),k.push(P)}else if(I.type==="chunk"&&I.chunk.type==="tool_result"){let F=I.chunk;c=l.length;let P=T.get(F.toolUseId);if(P&&(P.result=F.content,P.isError=F.isError,T.delete(F.toolUseId)),r.onContextProgress){let H=Date.now();if(H-w>=S){w=H;try{let U=r.onContextProgress();U instanceof Promise&&await U}catch(U){ze()&&console.error(" "+p.error("onContextProgress (status refresh) failed:"),U)}}}}if(I.type==="paused"){if(r.setPausedState?.(!0),await M(),E&&I.autoResume===!0){let F=new AbortController;b.abort=F;let P=I.resetsAt?I.resetsAt.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit"}):null,H=P?`Keep waiting \u2014 auto-resumes at ${P}`:"Keep waiting \u2014 auto-resume in progress",U="Switch model / provider (type /model after)",Q="Stop waiting",J=[p.warning(" \u23F3 Usage limit reached.")+(P?p.dim(` Auto-resumes at ${P}.`):""),p.dim(" Tip: run `claude login` in another terminal to switch account \u2014 this turn resumes on it automatically."),""];mr(E,{header:J,options:[H,U,Q],signal:F.signal,initialIndex:0}).then(se=>{if(b.abort=null,!se)return;let q=se[0];q===void 0||q===H||(y=!0,q===U&&(i??{fn:console.log}).fn(p.dim(" Hint: type /model <name> to switch, then send your message again.")),t.interrupt().catch(le=>{ze()&&console.error(" "+p.error("picker pause-interrupt session.interrupt() failed:"),le)}))}).catch(se=>{ze()&&console.error(" "+p.error("picker promise rejected:"),se)})}else(i??{fn:console.log}).fn(iC({reason:I.reason,...I.resetsAt!==void 0?{resetsAt:I.resetsAt}:{},...I.accountId!==void 0?{accountId:I.accountId}:{},...I.autoResume!==void 0?{autoResume:I.autoResume}:{}}));continue}if(I.type==="resumed"){r.setPausedState?.(!1),b.abort?.abort(),b.abort=null;let F=I.hotSwapped&&I.accountId?`\u25B6 Resumed on ${I.accountId}`:"\u25B6 Resumed";l="",c=0,d=!1,k.length=0,T.clear(),f=!1,g=void 0,u=!1,C=D(),m=!1,await N(),(i??{fn:console.log}).fn(p.success(F));continue}if(I.type==="error"){await M(),Ns(Ms(I.error)),u=!0;continue}C.process(I),I.type==="done"&&(f=!0,g=I.metadata)}}),await M(),h){let I=i?i.fn:console.log,F=E?E.getPendingCount():0,P=F>0?` \xB7 ${F} queued`:"";I(p.warning(`\u23F8 Stopped${P} \u2014 work so far kept.`)+p.dim(" Send a message to continue.")),I("")}if(y){let I=i?i.fn:console.log;I(p.dim("\u25B6 Ending wait \u2014 running your next command\u2026")),I("")}if(f&&!h&&!y){qi(n,a,l,g,k),r.onTurnComplete&&await r.onTurnComplete(a,l).catch(()=>{}),pl(process.stdout),oB(process.stdout,"afk: turn complete");let I=P=>{i?i.fn(P):console.log(P)},F=rb(l);if(F){I(NW(F)),I("");let P=PB(k);if(r.onTerminalState)try{r.onTerminalState(F,{doneHasCorroboratingEvidence:P})}catch{}if(n.permissionMode==="autonomous"){let H=F.kind==="done"&&Lc().verifyDone===!0&&!P;OB(F,void 0,{unverified:H})}}if(Rpe(g,n,I),r.onAfterTurn){let P=r.onAfterTurn();P instanceof Promise&&await P.catch(()=>{})}}}catch(j){await M(),u||Ns(Ms(j))}finally{await M(),ml(process.stdout,ru(process.cwd(),!1)),i&&(i.fn=i.idleFn,i.suppressSubagentCompletion=!1),r.setActiveCompositor?.(null),r.setInterruptNotifier?.(null),r.setBackgroundHandler?.(null),r.setSoftStopHandler?.(null),r.setPausedState?.(!1),r.setPauseInterruptHandler?.(null),b.abort?.abort(),b.abort=null,r.setInFlight(!1),r.rearmStatus?.()}}function xpe(e,t){let n=Math.round(e*100),r=pe(t);if(e>=1){let o=Math.round((e-1)*t);return{tier:"over",text:` context OVER ${Math.round(t/1e3)}k tok by ~${pe(o)} tok \u2014 model output may be silently truncated`}}return e>=.95?{tier:"near",text:` context ${n}% used of ${r} \u2014 near limit; output may soon truncate (consider /clear or a fresh session)`}:e>=.8?{tier:"caution",text:` context ${n}% used of ${r} \u2014 approaching limit`}:e>.5?{tier:"normal",text:` context ${n}% used of ${r}`}:{tier:"quiet",text:null}}function Rpe(e,t,n=console.log){if(!e)return;let r=[];e.durationMs&&r.push(xe(e.durationMs)),e.totalCostUsd!==void 0&&r.push(dt(e.totalCostUsd));let o=Number(e.usage?.input_tokens??0),i=Number(e.usage?.output_tokens??0);o+i>0&&r.push(pe(o+i)+" tok"),r.length>0&&n(p.dim(" \u25E6 "+r.join(" \xB7 ")));let s=uE(t),a=Vt(t.model),l=xpe(s,a);if(l.text!==null){let d=l.tier==="over"||l.tier==="near"?p.error:l.tier==="caution"?p.warning:p.dim;n(d(l.text))}let c=LW(Ih(Lp()),new Date,{autoResume:x_()});if(c.text!==null){let d=c.tier==="over"||c.tier==="near"?p.error:c.tier==="caution"?p.warning:p.dim;n(d(c.text))}n("")}var Ape=5e3,Cpe=3,_pe="[auto-resume] The background task above has finished. Continue the work it was dispatched for.";async function Ipe(e,t){if(e.firstTurnHook&&e.stats.totalTurns===0){let n=e.firstTurnHook;e.firstTurnHook=void 0;try{await n(t)}catch(r){e.completionWriter.fn(p.warning("\u26A0 ")+"first-turn hook failed: "+(r instanceof Error?r.message:String(r)))}}}async function HW(e,t,n,r,o,i,s,a){let{contextPane:l,loopStageBar:c,verdictLedger:d,shellPassthrough:u,bgResultNotifier:m}=s,f=null,g=[];e.session.current.waitForInitialization().then(async O=>{ze()&&(f=Dh(O)),await Pu(e.session.current),ze()&&(g=kx())}).catch(()=>{});let h=e.initialInput!==void 0?{text:e.initialInput,attachments:[]}:void 0,y,b=!1,w=!1,S,k,T,A=0;for(m.onInjectable=()=>{A>=Cpe||!o.isAwaitingInput()||!o.bufferIsEmpty()||(A++,pl(process.stdout),h={text:_pe,attachments:[]},o.abortPendingRead())};;){if(f&&(e.replRenderer.writeLine(f),e.replRenderer.writeLine(""),f=null),g.length>0){for(let _ of g)e.replRenderer.writeLine(_);e.replRenderer.writeLine(""),g=[]}let O=u.drainNotifications();for(let{job:_,result:$}of O){let I=$.errorReason===void 0?"\u2713":"\u2717",F=$.errorReason==="abort"?"killed":$.errorReason==="timeout"?"timed out":$.errorReason==="signal-killed"?"killed by signal":`exit ${$.exitCode??0}`,P=Math.max(0,Math.round($.durationMs/100)/10);e.replRenderer.writeLine(p.dim(` ${I} [${_.id}] ${F} \xB7 ${P}s \xB7 `)+_.command)}let E=m.drainNotifications();for(let{job:_}of E){let $=_.status==="completed"?"\u2713":_.status==="failed"?"\u2717":"\u2298",I=_.endedAt!==void 0?Math.max(0,Math.round((_.endedAt-_.startedAt)/100)/10):0,F=_.label.length>60?`${_.label.slice(0,60)}\u2026`:_.label;e.replRenderer.writeLine(p.dim(` ${$} [${_.jobId}] subagent ${_.status} \xB7 ${I}s \xB7 `)+F)}let D=l.renderIfChanged(e.stats.sessionId);if(D.length>0){for(let _ of D)e.replRenderer.writeLine(_);e.replRenderer.writeLine("")}let C,M;if(h===void 0){let _=await e.session.current.takePendingPlanExitSeed();_!==void 0&&(e.stats.permissionMode=_.mode,h={text:_.message,attachments:[]})}if(h!==void 0){let _=h;h=void 0;let $=Fl(e.stats.permissionMode),I=ts({buffer:_.text,promptText:$,isTTY:!!process.stdout.isTTY,attachmentSummary:kl([..._.attachments])});e.replRenderer.writeLine(I),C=_.text.trim(),M=_.attachments}else{let _=y;y=void 0;let $=await o.readLine({promptFn:()=>Fl(e.stats.permissionMode),..._!==void 0?{initialBuffer:_}:{},onSigint:r,onShiftTab:()=>{Zy(e.slashCtx).catch(()=>{}),e.statusLine.rearm()}});C=$.text.trim(),M=$.attachments}if(!C&&M.length===0)continue;if(C.startsWith("!")){let _=/^(0|false|off|no)$/i.test(v.AFK_SHELL_PASSTHROUGH??"");if(e.options.shellPassthrough!==!1&&!_&&(b||(b=!0,e.replRenderer.writeLine(p.dim(" \u2139 ! prefix shells out. Pass --no-shell-passthrough (or set AFK_SHELL_PASSTHROUGH=0) to send ! text to the model instead."))),await u.dispatch(C))){e.statusLine.rearm();continue}}let N=!1;if(C.startsWith("/")){let _=await bB(C,e.slashCtx,M);if(_.handled){if(_.result==="exit"){e.rl.close();return}if((C==="/clear"||C.startsWith("/clear "))&&(await t.rotateOnClear(),e.replRenderer.writeLine(p.dim(` transcript: ${t.path()}`)),d.reset(),S=void 0),_.result!==null&&typeof _.result=="object"&&"kind"in _.result&&_.result.kind==="submit"){h={text:_.result.message,attachments:M??[]},e.statusLine.rearm();continue}if(_.result!==null&&typeof _.result=="object"&&"kind"in _.result&&_.result.kind==="prefill"){y=_.result.message,e.statusLine.rearm();continue}e.statusLine.rearm();continue}N=!0}a.push(C),await Ipe(e,C);let j=C;if(N){let _=dE(C);if(_){let $=_.name.replace(/^\//,"").split(":").pop()??"";if($&&bx($)){let I={skillName:$,rawArgs:_.args,source:"plugin",capabilities:{compose:!0,subagents:!0}},F=e.session.current.sessionId,P=us(F),H=Date.now();W(`[afk trace] preflight.start commandName=${$}`);let U=!1,Q=await ds(I,{cwd:e.stats.cwd??process.cwd(),artifactDir:P},J=>{ze()&&e.replRenderer.writeLine(p.warning(`\u26A0 preflight(${$}) failed: `)+(J instanceof Error?J.message:String(J)))});U=Q!==null,W(`[afk trace] preflight.end commandName=${$} durationMs=${Date.now()-H} success=${U}`),j=Sx(Q?.manifestBlock,C)}}}let B=u.drainInjections();B.length>0&&(j=B+j);let K=m.drainInjections();if(K.length>0&&(j=K+j),S!==void 0&&(j=S+`
|
|
1768
1768
|
|
|
1769
1769
|
`+j,S=void 0),e.hookRegistry)try{let _={event:"UserPromptSubmit",prompt:j,sessionId:e.stats.sessionId},$=await e.hookRegistry.dispatch(_);$.injectContext&&(j=$.injectContext+j)}catch(_){if(_ instanceof ve){e.replRenderer.writeLine(p.warning("\u2298 Turn blocked by hook")+(_.reason?p.dim(`: ${Ir(_.reason)}`):"")),e.statusLine.rearm();continue}if(_ instanceof Zn){e.replRenderer.writeLine(p.warning("\u2298 Turn blocked by hook")+p.dim(`: handler timed out after ${_.timeoutMs}ms`)),e.statusLine.rearm();continue}throw _}if(k=void 0,T=void 0,await jW({text:j,attachments:M},e.session.current,e.stats,{setInFlight(_){n.turnInFlight=_},...e.subagentControl?{subagentControl:e.subagentControl}:{},async onUserMessage(_){await t.appendUser(_)},async onTurnComplete(_,$){if(await t.appendTurn(_,$),e.stats.sessionId)try{Fo(e.stats)}catch(I){w||(w=!0,e.replRenderer.writeLine(p.warning("\u26A0 ")+"session autosave failed \u2014 this conversation may not be resumable: "+(I instanceof Error?I.message:String(I))))}},async onAfterTurn(){await e.contextSampler.onTurn(e.stats.totalTurns),await e.gitStatusSampler.refresh(),e.statusLine.rearm(),c?.repaint("observing")},rearmStatus:()=>e.statusLine.rearm(),onTerminalState:(_,$)=>{d?.push(_),k=_.kind,T=$?.doneHasCorroboratingEvidence},setActiveCompositor:_=>{n.activeCompositor=_},setInterruptNotifier:_=>{n.notifyInterrupting=_},scrollRegion:e.statusLine,getCompositor:()=>o.getCompositor(),setBackgroundHandler:_=>o.setBackgroundHandler(_),setSoftStopHandler:i,setPausedState:_=>o.setPausedState(_),setPauseInterruptHandler:_=>o.setPauseInterruptHandler(_),async onContextProgress(){await e.contextSampler.refresh(),e.statusLine.repaint(Un(e.stats,e.contextSampler,e.gitStatusSampler))},...c?{onStageChange:_=>c.repaint(_)}:{}},e.stats.thinkingUi??e.options.thinkingUi,e.completionWriter,o.toRunTurnRefs(Fl(e.stats.permissionMode))),e.hookRegistry)try{let _=await e.hookRegistry.dispatch({event:"Stop",sessionId:e.stats.sessionId,...k!==void 0?{terminalState:k}:{},...T!==void 0?{doneHasCorroboratingEvidence:T}:{}},void 0,Ape);_.injectContext&&_.injectContext.trim().length>0&&(S=_.injectContext)}catch(_){if(_ instanceof mt)throw _;_ instanceof Zn?(W("[stop hook] handler timed out"),e.completionWriter.fn(p.dim(" [stop hook] timed out"))):_ instanceof ve?e.completionWriter.fn(p.dim(` [stop hook] blocked: ${Ir(_.reason??"no reason given")}`)):W("[stop hook] unexpected error: "+String(_))}}}function Ppe(e,t){if(e!==void 0){let n=e.toLowerCase();return!(n==="0"||n==="false"||n==="off"||n==="no")}return typeof t=="boolean"?t:!0}async function WW(e,t,n,r){let o=await SW(),i=new Qy({rl:e.rl,history:o,statusLine:e.statusLine}),s=Ppe(v.AFK_SUGGEST_GHOST,e.suggestGhostConfig),a;try{let{installSoftStop:l}=await xW(e,i,n,t,r,s,{getLoopStageBar:()=>a?.loopStageBar});a=DW(e,n),await HW(e,t,n,r,i,l,a,o)}finally{n.tryAbortShellForeground=null,a?.shellPassthrough.drainOnExit(),a?.bgResultNotifier.dispose(),a?.loopStageBar.stop(),a?.bgStatusBar.stop(),a?.verdictLedger.stop(),a?.contextPane.dispose();let l=c=>console.log(c);e.completionWriter.fn=l,e.completionWriter.idleFn=l,await i.dispose(),e.inputSurfaceRef&&(e.inputSurfaceRef.current=null)}}Mc();pa();import{execFile as Mpe}from"node:child_process";import{dirname as Ope,isAbsolute as $pe,resolve as Dpe}from"node:path";import{promisify as Fpe}from"node:util";var KW=Fpe(Mpe),Lpe=3e3,Npe=new Set(["empty","orphaned-dir","orphaned-registration","dead-owner"]);async function Bpe(){let t=(await KW("git",["rev-parse","--git-common-dir"])).stdout.trim();if(!t)throw new Error("Not in a git repository.");let n=$pe(t)?t:Dpe(process.cwd(),t);return Ope(n)}async function GW(e){if(e?.disabled)return{ran:!1,removedCount:0,skippedReason:"disabled"};let t;try{t=await Bpe()}catch{return{ran:!1,removedCount:0,skippedReason:"not-in-repo"}}let n,r=new Promise(o=>{n=setTimeout(()=>o("timeout"),Lpe)});try{let o=fn({execFile:KW,repoRoot:t,dryRun:!1,scope:"interactive",bypassSoftLaunch:!0}),i=await Promise.race([o,r]);if(i==="timeout")return{ran:!1,removedCount:0,skippedReason:"timeout"};let s=i;return s.warnings.some(c=>c.toLowerCase().includes("contested"))?{ran:!1,removedCount:0,skippedReason:"lock-contested"}:{ran:!0,removedCount:s.candidates.filter(c=>Npe.has(c.verdict)&&s.removed.includes(c.path)).length}}catch{return{ran:!1,removedCount:0,skippedReason:"error"}}finally{n&&clearTimeout(n)}}$p();Mc();import{promises as Upe}from"node:fs";import{dirname as jpe,join as JW}from"node:path";import{randomBytes as Hpe}from"node:crypto";var Wpe=["Generate a 2-4 word kebab-case slug describing this work request.","Rules:","- ASCII lowercase letters and digits only, separated by single hyphens","- 2 to 4 hyphen-separated words","- Maximum 30 characters total","- No prefix, no quotes, no punctuation other than hyphens","- Output ONLY the slug \u2014 no explanation, no preamble","Examples: fix-cleanup-race, add-telegram-allowlist, refactor-prompt-loader, debug-flaky-test"].join(`
|
|
1770
|
-
`),qW=/^[a-z0-9]+(-[a-z0-9]+){1,3}$/,qx=30,Kpe=1024,Gpe=8e3,qpe="haiku";async function zpe(e,t){let n=e.trim();if(n.length===0)return t.onSkip?.("empty-message"),null;if(n.startsWith("/"))return t.onSkip?.("slash-command"),null;let r=Xpe(n,Kpe),o=new AbortController,i=setTimeout(()=>o.abort(),t.timeoutMs??Gpe),s=t.signal?Qpe([t.signal,o.signal]):o.signal,a;try{t.slugGenerator?a=await t.slugGenerator(r,s):a=await Gs({token:t.token,model:t.model??qpe,system:Wpe,user:r,maxTokens:32,signal:s})}catch(u){let m=u instanceof Error?u.message:String(u);return t.onSkip?.("slug-generator-error",m.slice(0,200)),null}finally{clearTimeout(i)}let l=Jpe(a);if(l===null)return t.onSkip?.("invalid-slug-output",a.slice(0,60)),null;let c=jpe(t.worktreePath);return await Ype(l,c)}function Jpe(e){let t=e.trim().toLowerCase();if(t.length===0)return null;if(qW.test(t)&&t.length<=qx)return t;let n=t.replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");if(n.length===0)return null;let r=n.split("-").filter(i=>i.length>0).slice(0,4);if(r.length<2)return null;let o=r[0];for(let i=1;i<r.length;i++){let s=`${o}-${r[i]}`;if(s.length>qx)break;o=s}return qW.test(o)?o:null}async function Ype(e,t){if(!await Vpe(JW(t,e)))return e;let n=Hpe(2).toString("hex");return`${e.split("-").slice(0,3).join("-").slice(0,qx-5)}-${n}`}async function Vpe(e){try{return await Upe.access(e),!0}catch{return!1}}function Xpe(e,t){let n=Buffer.from(e,"utf8");if(n.length<=t)return e;let r=t;for(;r>0&&n[r]!==void 0&&(n[r]&192)===128;)r--;return n.slice(0,r).toString("utf8")}function Qpe(e){let t=AbortSignal.any;if(typeof t=="function")return t.call(AbortSignal,e);let n=new AbortController;for(let r of e){if(r.aborted)return n.abort(r.reason),n.signal;r.addEventListener("abort",()=>n.abort(r.reason),{once:!0})}return n.signal}async function YW(e){let t,n,r=JW(e.deferred.repoRoot,".afk-worktrees","unnamed"),o=await zpe(e.message,{token:e.token,...e.model!==void 0?{model:e.model}:{},...e.timeoutMs!==void 0?{timeoutMs:e.timeoutMs}:{},worktreePath:r,...e.signal!==void 0?{signal:e.signal}:{},...e.slugGenerator!==void 0?{slugGenerator:e.slugGenerator}:{},onSkip:(a,l)=>{t=a,n=l}}),i=t??"unknown",s=n;if(o!==null){let l=`${em(e.branchPrefix)}${o}`;try{let c=await e.deferred.create(l);return zW(e.session,c.path),{status:"created",path:c.path,branch:c.branch,slug:o}}catch(c){i="create-failed",s=(c instanceof Error?c.message:String(c)).slice(0,200)}}try{let a=await e.deferred.create(!0);return zW(e.session,a.path),{status:"created-fallback",path:a.path,branch:a.branch,reason:i,...s!==void 0?{detail:s}:{}}}catch(a){return{status:"failed",reason:a instanceof Error?a.message:String(a)}}}function zW(e,t){e&&e.setCwd(t),Zpe(t)}function Zpe(e){try{process.chdir(e)}catch{}}qt();z();import{spawn as XW}from"child_process";import{existsSync as QW,mkdirSync as ome,readFileSync as ZW,unlinkSync as VW,writeFileSync as eK}from"fs";import{get as ime}from"https";import{join as tK}from"path";import{readFileSync as eme}from"fs";import{dirname as tme,join as nme}from"path";import{fileURLToPath as rme}from"url";function br(){try{return"5.83.
|
|
1770
|
+
`),qW=/^[a-z0-9]+(-[a-z0-9]+){1,3}$/,qx=30,Kpe=1024,Gpe=8e3,qpe="haiku";async function zpe(e,t){let n=e.trim();if(n.length===0)return t.onSkip?.("empty-message"),null;if(n.startsWith("/"))return t.onSkip?.("slash-command"),null;let r=Xpe(n,Kpe),o=new AbortController,i=setTimeout(()=>o.abort(),t.timeoutMs??Gpe),s=t.signal?Qpe([t.signal,o.signal]):o.signal,a;try{t.slugGenerator?a=await t.slugGenerator(r,s):a=await Gs({token:t.token,model:t.model??qpe,system:Wpe,user:r,maxTokens:32,signal:s})}catch(u){let m=u instanceof Error?u.message:String(u);return t.onSkip?.("slug-generator-error",m.slice(0,200)),null}finally{clearTimeout(i)}let l=Jpe(a);if(l===null)return t.onSkip?.("invalid-slug-output",a.slice(0,60)),null;let c=jpe(t.worktreePath);return await Ype(l,c)}function Jpe(e){let t=e.trim().toLowerCase();if(t.length===0)return null;if(qW.test(t)&&t.length<=qx)return t;let n=t.replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");if(n.length===0)return null;let r=n.split("-").filter(i=>i.length>0).slice(0,4);if(r.length<2)return null;let o=r[0];for(let i=1;i<r.length;i++){let s=`${o}-${r[i]}`;if(s.length>qx)break;o=s}return qW.test(o)?o:null}async function Ype(e,t){if(!await Vpe(JW(t,e)))return e;let n=Hpe(2).toString("hex");return`${e.split("-").slice(0,3).join("-").slice(0,qx-5)}-${n}`}async function Vpe(e){try{return await Upe.access(e),!0}catch{return!1}}function Xpe(e,t){let n=Buffer.from(e,"utf8");if(n.length<=t)return e;let r=t;for(;r>0&&n[r]!==void 0&&(n[r]&192)===128;)r--;return n.slice(0,r).toString("utf8")}function Qpe(e){let t=AbortSignal.any;if(typeof t=="function")return t.call(AbortSignal,e);let n=new AbortController;for(let r of e){if(r.aborted)return n.abort(r.reason),n.signal;r.addEventListener("abort",()=>n.abort(r.reason),{once:!0})}return n.signal}async function YW(e){let t,n,r=JW(e.deferred.repoRoot,".afk-worktrees","unnamed"),o=await zpe(e.message,{token:e.token,...e.model!==void 0?{model:e.model}:{},...e.timeoutMs!==void 0?{timeoutMs:e.timeoutMs}:{},worktreePath:r,...e.signal!==void 0?{signal:e.signal}:{},...e.slugGenerator!==void 0?{slugGenerator:e.slugGenerator}:{},onSkip:(a,l)=>{t=a,n=l}}),i=t??"unknown",s=n;if(o!==null){let l=`${em(e.branchPrefix)}${o}`;try{let c=await e.deferred.create(l);return zW(e.session,c.path),{status:"created",path:c.path,branch:c.branch,slug:o}}catch(c){i="create-failed",s=(c instanceof Error?c.message:String(c)).slice(0,200)}}try{let a=await e.deferred.create(!0);return zW(e.session,a.path),{status:"created-fallback",path:a.path,branch:a.branch,reason:i,...s!==void 0?{detail:s}:{}}}catch(a){return{status:"failed",reason:a instanceof Error?a.message:String(a)}}}function zW(e,t){e&&e.setCwd(t),Zpe(t)}function Zpe(e){try{process.chdir(e)}catch{}}qt();z();import{spawn as XW}from"child_process";import{existsSync as QW,mkdirSync as ome,readFileSync as ZW,unlinkSync as VW,writeFileSync as eK}from"fs";import{get as ime}from"https";import{join as tK}from"path";import{readFileSync as eme}from"fs";import{dirname as tme,join as nme}from"path";import{fileURLToPath as rme}from"url";function br(){try{return"5.83.8"}catch{}try{let e=tme(rme(import.meta.url));for(let t of["../../package.json","../package.json"])try{let n=JSON.parse(eme(nme(e,t),"utf-8"));if(typeof n.version=="string")return n.version}catch{}}catch{}return"0.0.0-unknown"}G();var sme=64*1024,ame=10800*1e3,lme=800,cme=3600*1e3,dme="update-check.json",ume="pending-update.json";function zx(){return tK(_s(),dme)}function Lu(){return tK(_s(),ume)}function Jx(){let e=_s();QW(e)||ome(e,{recursive:!0})}function nK(e,t){let n=a=>a.split(/[-+]/,1)[0]??a,r=a=>a.includes("-"),o=n(e).split(".").map(Number),i=n(t).split(".").map(Number),s=Math.max(o.length,i.length);for(let a=0;a<s;a++){let l=o[a]??0,c=i[a]??0;if(c>l)return!0;if(c<l)return!1}return r(e)&&!r(t)}function rK(){try{let e=ZW(zx(),"utf-8"),t=JSON.parse(e);if(typeof t.latestVersion=="string"&&typeof t.checkedAt=="number")return t}catch{}return null}function oK(){try{Jx();let e=`
|
|
1771
1771
|
const https = require('https');
|
|
1772
1772
|
const fs = require('fs');
|
|
1773
1773
|
const url = 'https://registry.npmjs.org/agent-afk/latest';
|