agent-afk 5.106.0 → 5.106.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs CHANGED
@@ -24,7 +24,7 @@ ${r}
24
24
  ### end \xB7 ${t.reason??"unknown"} \xB7 ${n}
25
25
  `}function KP(e){if(!w9(e))return null;let t=VI(e.sessionId),n=y9(t,`${S9(e.subagentId)}.md`),r=[],o=0,i=!1,s=!1,a=!1,l=Promise.resolve(),c=d=>{if(i)return;o>=HP&&(i=!0,d=`
26
26
  <!-- CAP REACHED at ${HP} bytes \u2014 capture stopped -->
27
- `),o+=Buffer.byteLength(d,"utf8");let p=s?d:`${v9(e)}${d}`;s=!0,l=l.then(async()=>{await h9(t,{recursive:!0,mode:448}),await g9(n,p,{encoding:"utf8",mode:384})}).catch(f=>{lt("subagent-output-capture",e.sessionId??"unknown","write",f)})},u=()=>{if(r.length===0)return;let d=r.join("").trim();r=[],d.length>0&&(c(Qm("say",{text:d})),a=!0)};return{observe(d){try{if(d.type==="chunk"){let p=d.chunk;if(p.type==="content"){r.push(p.content);return}if(p.type==="tool_use_detail"){if(p.pending)return;u(),c(Qm("tool",{toolName:p.toolName,toolInput:p.toolInputRaw??p.toolInput}))}return}if(d.type==="message"){if(!a&&r.length===0){let p=d.message.content.trim();p.length>0&&(c(Qm("say",{text:p})),a=!0)}return}(d.type==="done"||d.type==="error")&&(u(),a=!1)}catch(p){lt("subagent-output-capture",e.sessionId??"unknown","observe",p)}},end(d){try{u(),c(Qm("end",{reason:d}))}catch(p){lt("subagent-output-capture",e.sessionId??"unknown","end",p)}}}}var jP,HP,b9,GP=v(()=>{"use strict";W();G();Vm();Co();ek();jP=4*1024,HP=512*1024,b9="<!-- Best-effort secret redaction only. Connection strings, PEM blocks, and PII are NOT caught. -->"});async function Di(e,t){if(e)try{await e.write({kind:"tool_call",payload:t})}catch(n){lt("trace.emit",e,"tool_call",n)}}async function mn(e,t){if(e)try{await e.write({kind:"hook_decision",payload:t})}catch(n){lt("trace.emit",e,"hook_decision",n)}}async function Fi(e,t){if(e)try{await e.write({kind:"subagent_lifecycle",payload:t})}catch(n){lt("trace.emit",e,"subagent_lifecycle",n)}}async function Li(e,t){if(e)try{await e.write({kind:"background_agent",payload:t})}catch(n){lt("trace.emit",e,"background_agent",n)}}async function qP(e,t){if(e)try{await e.write({kind:"budget",payload:t})}catch(n){lt("trace.emit",e,"budget",n)}}async function zP(e,t){if(e)try{await e.write({kind:"abort",payload:t})}catch(n){lt("trace.emit",e,"abort",n)}}async function Zm(e,t){if(e)try{await e.write({kind:"compaction",payload:t})}catch(n){lt("trace.emit",e,"compaction",n)}}async function JP(e,t){if(e)try{await e.write({kind:"closure",payload:t})}catch(n){lt("trace.emit",e,"closure",n)}}async function ct(e,t){if(e)try{await e.write({kind:"browser_event",payload:t})}catch(n){lt("trace.emit",e,"browser_event",n)}}async function VP(e,t){if(e)try{await e.write({kind:"queued_user_message",payload:t})}catch(n){lt("trace.emit",e,"queued_user_message",n)}}async function re(e,t){if(e)try{await e.write({kind:"session_phase",payload:t})}catch(n){lt("trace.emit",e,"session_phase",n)}}var de=v(()=>{"use strict";Vm()});function YP(e){let t=[...e.oauthEntries??[],...e.effort?[e.effortEntry]:[],...e.extendedCacheTtl?[e.extendedCacheEntry]:[],...e.fast?[k9]:[]].filter(Boolean);return[...new Set(t)].join(",")||void 0}var k9,XP=v(()=>{"use strict";k9="fast-mode-2026-02-01"});function ef(e){return e.startsWith("sk-ant-oat01-")?"oauth":"api-key"}function mu(e,t,n,r){let o=t==="oauth"?{authToken:e}:{apiKey:e},i=typeof n=="string"&&n.length>0?{...o,baseURL:n}:o;return r?{...i,fetch:r}:i}function _o(e,t,n,r,o,i){let s=YP({oauthEntries:e==="oauth"?T9.split(","):[],effort:e==="oauth"&&r===!0,extendedCacheTtl:o,fast:i,effortEntry:E9,extendedCacheEntry:QP});return e!=="oauth"?s?{"anthropic-beta":s}:{}:{"anthropic-beta":s,"x-app":"cli","User-Agent":R9,"X-Claude-Code-Session-Id":t,"x-client-request-id":n}}function ZP(e){return e!=="oauth"?null:[{type:"text",text:x9}]}var QP,T9,E9,R9,x9,Ni=v(()=>{"use strict";XP();QP="extended-cache-ttl-2025-04-11",T9=`claude-code-20250219,oauth-2025-04-20,interleaved-thinking-2025-05-14,${QP}`,E9="effort-2025-11-24",R9="claude-cli/1.0.0 (external, cli)",x9="x-anthropic-billing-header: cc_version=1.0.0.test; cc_entrypoint=cli; cch=00000;"});function nf(e){ok=e}function tk(e){if(e===void 0)return;let t=e.trim();return t.length>0?t:void 0}function tf(e,t,n){let r={},o=tk(e);o&&(r.id=o);let i=tk(t);i&&(r.baseUrl=i);let s=tk(n);return s&&(r.apiKey=s),r}function A9(){return{local:tf(T.AFK_MODEL_LOCAL,T.AFK_MODEL_LOCAL_BASE_URL,T.AFK_MODEL_LOCAL_API_KEY),small:tf(T.AFK_MODEL_SMALL,T.AFK_MODEL_SMALL_BASE_URL,T.AFK_MODEL_SMALL_API_KEY),medium:tf(T.AFK_MODEL_MEDIUM,T.AFK_MODEL_MEDIUM_BASE_URL,T.AFK_MODEL_MEDIUM_API_KEY),large:tf(T.AFK_MODEL_LARGE,T.AFK_MODEL_LARGE_BASE_URL,T.AFK_MODEL_LARGE_API_KEY)}}function ak(e){let t=A9(),n={};for(let r of fu){let o=Bi[r],i=e?.[r],s=t[r],a={id:s.id??i?.id??o.id},l=i?.name;l&&(a.name=l);let c=i?.provider;c&&(a.provider=c);let u=s.baseUrl??i?.baseUrl;u&&(a.baseUrl=u);let d=s.apiKey??i?.apiKey;d&&(a.apiKey=d),n[r]=a}return n}function _a(e){return e||ok||ak()}function Ia(e,t=_a()){let n=e.trim().toLowerCase();if(!(!n||n===nM)){for(let r of fu){let o=t[r].name;if(o&&o.trim().toLowerCase()===n)return r}if(n==="local"||n==="small"||n==="medium"||n==="large")return n}}function Ui(e,t=_a()){if(e===void 0)return{id:""};let n=Ia(e,t);if(n)return t[n];let r=sk[e.trim().toLowerCase()];return r?{id:r}:{id:e}}function cr(e,t=_a()){if(e!==void 0)return Ui(e,t).id}function Pa(e,t=_a()){if(e===void 0)return;let n=Ia(e,t);if(n&&t[n].id.trim()===""){let r=n.toUpperCase();return`The "${n}" model tier is not configured (no model id). Set AFK_MODEL_${r}=<id> (optionally AFK_MODEL_${r}_BASE_URL / AFK_MODEL_${r}_API_KEY) or "models.${n}" in afk.config.json, then retry.`}}function rM(e){let t={};if(!e||typeof e!="object")return t;let n=e;for(let r of fu){let o=_9(n[r]);o&&(t[r]=o)}return t}function oM(e){if(typeof e!="string")return;let t=e.trim().toLowerCase();if(t==="anthropic"||t==="anthropic-direct")return"anthropic";if(t==="openai"||t==="openai-compatible")return"openai";if(t==="chatgpt-oauth"||t==="chatgpt")return"chatgpt-oauth"}function Ca(e){return typeof e=="string"?e.trim():""}function eM(e){return/[\x00-\x1f\x7f]/.test(e)}function _9(e){if(typeof e=="string"){let t=e.trim();return t?{id:t}:void 0}if(e&&typeof e=="object"){let t=e,n=Ca(t.id);if(!n)return;let r={id:n},o=Ca(t.name);o&&(r.name=o);let i=oM(t.provider);i&&(r.provider=i);let s=Ca(t.baseUrl);s&&(r.baseUrl=s);let a=Ca(t.apiKey);return a&&(r.apiKey=a),r}}function iM(e){if(!e||typeof e!="object"||Array.isArray(e))return{ok:!1,error:'model binding must be an object with at least an "id"'};let t=e;if("apiKey"in t||"api_key"in t)return{ok:!1,error:"per-slot API keys are credentials; set AFK_MODEL_<TIER>_API_KEY via `afk config env set` instead of afk.config.json"};if("baseUrl"in t||"base_url"in t)return{ok:!1,error:"per-slot baseUrl is an endpoint-redirect credential vector; set AFK_MODEL_<TIER>_BASE_URL via `afk config env set` instead of afk.config.json"};let n=Ca(t.id);if(!n)return{ok:!1,error:'model binding requires a non-empty "id"'};if(eM(n))return{ok:!1,error:'model binding "id" must not contain control characters'};let r={id:n},o=Ca(t.name);if(o){if(eM(o))return{ok:!1,error:'model binding "name" must not contain control characters'};if(C9.has(o.trim().toLowerCase()))return{ok:!1,error:`model binding "name" must not shadow a built-in alias ("${o}")`};r.name=o}if(t.provider!==void 0&&t.provider!==""){let i=oM(t.provider);if(!i)return{ok:!1,error:'model binding "provider" must be one of: anthropic, openai (aliases: anthropic-direct, openai-compatible)'};r.provider=i}return{ok:!0,value:r}}var fu,tM,nk,rk,ik,Bi,nM,sk,gu,ok,C9,Pt=v(()=>{"use strict";W();fu=["local","small","medium","large"],tM="claude-haiku-4-5-20251001",nk="claude-sonnet-4-6",rk="claude-opus-5",ik="claude-fable-5",Bi={local:{id:""},small:{id:tM},medium:{id:nk},large:{id:rk}},nM="auto",sk={opus:rk,opus_1m:rk,sonnet:nk,sonnet_1m:nk,haiku:tM,fable:ik},gu=[...fu,...Object.keys(sk)];C9=new Set([...fu,nM,...Object.keys(sk)])});function hu(e){return e in lk}function ht(e){return cr(e)}var lk,fn=v(()=>{"use strict";Pt();lk={opus:Bi.large.id,opus_1m:Bi.large.id,sonnet:Bi.medium.id,sonnet_1m:Bi.medium.id,haiku:Bi.small.id,fable:ik}});import I9 from"@anthropic-ai/sdk";import{randomUUID as sM}from"node:crypto";async function Ma(e){let{token:t,model:n,system:r,user:o,maxTokens:i=64,signal:s,clientFactory:a}=e;if(!t)throw new Error("oneShotCompletion: token required");let l=ef(t),c=mu(t,l),u=a?a(c):new I9(c),d=sM(),p=sM(),f=_o(l,d,p),g=ht(n)??n,h={};Object.keys(f).length>0&&(h.headers=f),s&&(h.signal=s);let y=await u.messages.create({model:g,max_tokens:i,system:r,messages:[{role:"user",content:o}]},Object.keys(h).length>0?h:void 0),b=[];for(let k of y.content)k.type==="text"&&b.push(k.text);let w=b.join("").trim();return w.length===0&&console.warn("oneShotCompletion: response contained no text blocks \u2014 returning empty string"),w}var rf=v(()=>{"use strict";Ni();fn()});function O9(){let e=T.AFK_VISION_MODELS,t=[],n=[];if(e)for(let r of e.split(",")){let o=r.trim().toLowerCase();if(o)if(o.startsWith("!")){let i=o.slice(1).trim();i&&n.push(i)}else t.push(o)}return{enable:t,disable:n}}function aM(e,t){return e===t||e.includes(t)}function of(e){if(!e)return!1;let t=(cr(e)??e).trim();if(!t)return!1;let n=t.toLowerCase(),{enable:r,disable:o}=O9();return o.some(i=>aM(n,i))?!1:r.some(i=>aM(n,i))||P9.has(n)?!0:M9.some(i=>i.test(t))}function lM(e){let t=e.trim().toLowerCase();return t.includes("/")?t.slice(t.lastIndexOf("/")+1):t}function ji(e){return e?/^o[0-9]/.test(lM(e)):!1}function yu(e){if(!e)return!1;if(ji(e))return!0;let t=lM(e);return $9.some(n=>n.test(t))}var P9,M9,$9,Hi=v(()=>{"use strict";W();Pt();P9=new Set(["gpt-4o","gpt-4o-mini","gpt-4.1","gpt-4.1-mini","gpt-4.1-nano","gpt-4-turbo","o1","o3","o4-mini"]),M9=[/^claude-/i,/^gpt-4o/i,/^gpt-4\.1/i,/^gpt-4-turbo/i,/^gpt-4-vision/i,/^gpt-5/i,/(?:^|[/_-])(?:vl|vlm)(?:[/_.-]|$)/i,/(?:^|[/_-])(?:llava|pixtral|internvl|cogvlm|idefics|moondream|janus)/i,/(?:vision|minicpm-?[vo]|qwen[\d.]*-?vl|llama-?3\.2-\d+b-vision|gemma-3|phi-3\.5-vision|phi-4-multimodal)/i];$9=[/^gpt-5/]});function ck(e){let t=String(e).trim().toLowerCase(),n=sf[t];if(t.endsWith("_1m")&&n!==void 0)return n;let r=cr(e)??String(e);return sf[r]??sf[r.toLowerCase()]}function bu(e){return ck(e)??D9}function N9(e){if(!e)return!1;let t=e.trim().toLowerCase();return t?!!(t.includes("/")||t.startsWith("gpt-")||t.startsWith("gpt_")||ji(t)||t.startsWith("codex-")||t.startsWith("codex_")||t==="codex"):!1}function Yt(e){let t=String(e).trim().toLowerCase(),n=Oa[t];if(t.endsWith("_1m")&&n!==void 0)return n;let r=cr(e)??String(e),o=Oa[r]??Oa[r.toLowerCase()];return o!==void 0?o:N9(r)?L9:F9}function Wi(e){let t=Yt(e);if(String(e).trim().toLowerCase().endsWith("_1m"))return t;let r=cr(e)??String(e),o=cM[r]??cM[r.toLowerCase()];return o!==void 0?Math.min(t,o):t}var sf,D9,Oa,F9,L9,cM,Io=v(()=>{"use strict";Pt();Hi();sf={opus:128e3,opus_1m:128e3,sonnet:128e3,sonnet_1m:128e3,haiku:64e3,fable:128e3,"claude-opus-5":128e3,"claude-opus-4-8":128e3,"claude-sonnet-5":128e3,"claude-sonnet-4-6":128e3,"claude-haiku-4-5-20251001":64e3,"claude-fable-5":128e3,"gpt-5.5":128e3,"gpt-5.6":128e3,"gpt-5.6-sol":128e3,"gpt-5.6-terra":128e3,"gpt-5.6-luna":128e3},D9=64e3;Oa={opus:1e6,opus_1m:1e6,sonnet:1e6,sonnet_1m:1e6,haiku:2e5,fable:1e6,"claude-fable-5":1e6,"claude-sonnet-5":1e6,"claude-opus-5":1e6,"claude-sonnet-4-6":1e6,"gpt-4o":128e3,"gpt-4o-mini":128e3,"gpt-4.1":1e6,"gpt-4.1-mini":1e6,"gpt-5.5":1e6,"gpt-5.6":1e6,"gpt-5.6-sol":1e6,"gpt-5.6-terra":1e6,"gpt-5.6-luna":1e6,o1:2e5,"o1-mini":128e3,o3:2e5,"o3-mini":2e5,"o4-mini":2e5,"mlx-community/qwen3-30b-a3b-4bit":128e3,"mlx-community/qwen3-32b-4bit":128e3,"mlx-community/qwen2.5-coder-32b-instruct-4bit":131072},F9=2e5,L9=262144;cM={"claude-sonnet-5":2e5,"claude-opus-5":2e5,"claude-sonnet-4-6":2e5}});function uM(e){return(e.inputTokens??0)+(e.outputTokens??0)}function Xt(e){return e.contextWindowTokens??uM(e)}function wu(e){return e?{totalTokens:Xt(e),apiUsage:{input_tokens:e.inputTokens??0,output_tokens:e.outputTokens??0,cache_read_input_tokens:e.cachedInputTokens??0,cache_creation_input_tokens:e.cacheCreationTokens??0,context_window_tokens:Xt(e)}}:{totalTokens:0,apiUsage:null}}function Su(e,t,n){return t<=0||e<=0||n<=0||n>=1?!1:e/t>=n}function vu(e,t){return t<=0||e<=0?0:e/t}function $a(e){if(e===void 0||e===!1)return;if(e===!0)return B9;let t=e.threshold;if(!(typeof t!="number"||!Number.isFinite(t)||t<=0||t>=1))return t}var B9,ku=v(()=>{"use strict";B9=.9});function lf(e,t){let n=bu(t),r=e.maxOutputTokens;if(typeof r=="number"&&Number.isFinite(r)&&r>0){let o=Math.floor(r);if(o>n){let i=`max:${t}:${o}`;return af.has(i)||(af.add(i),console.warn(`[afk] maxOutputTokens ${o} exceeds the ${t} output ceiling (${n}); clamping to ${n}.`)),n}return o}return n}function dM(e){if(!e||e.length===0)return;let t=[];for(let n of e)n.user.length>0&&t.push({role:"user",content:n.user}),n.assistant.length>0&&t.push({role:"assistant",content:n.assistant});return t.length>0?t:void 0}function cf(e,t,n){switch(e.type){case"adaptive":return{type:"adaptive",display:"summarized"};case"disabled":return{type:"disabled"};case"enabled":{if(typeof n=="string"&&j9(n))return{type:"adaptive",display:"summarized"};if(t<=1024)throw new Error(`[afk] Extended thinking requires max_tokens > 1024 (the API constraint is 1024 <= budget_tokens < max_tokens), but the resolved output cap is ${t}. Raise --max-output-tokens / AFK_MAX_OUTPUT_TOKENS above 1024, or disable thinking with --thinking disabled.`);let r=Math.floor(t*H9),o=Math.max(1024,t-1-r),i=e.budgetTokens!==void 0&&Number.isFinite(e.budgetTokens)?Math.floor(e.budgetTokens):void 0,s=Math.min(Math.max(i??o,1024),o);if(i!==void 0&&i>o){let a=`think:${n??"default"}:${i}:${t}`;af.has(a)||(af.add(a),console.warn(`[afk] thinking budgetTokens ${i} leaves too little of max_tokens ${t} for the reply; clamping to ${o}.`))}return{type:"enabled",budget_tokens:s,display:"summarized"}}}}function uf(e,t){if(e!==void 0)return e;let n=t.toLowerCase();if(/(claude-)?(opus|sonnet)-(4-[678]|5)/.test(n))return"max"}var U9,j9,af,H9,df=v(()=>{"use strict";Io();ku();U9=e=>/opus-4-(7|[89])/.test(e),j9=e=>U9(e)||/(claude-)?(opus|sonnet)-5/.test(e),af=new Set,H9=.25});import uk from"path";import{dirname as W9}from"path";import{appendFileSync as K9,mkdirSync as G9}from"fs";var Po,pf=v(()=>{"use strict";G();Po=class{hooks;constructor(t){this.hooks=t}addReadRoot(t,n="slash",r){this.hooks.ensureInitialized?.();let o=this.hooks.getReadRoots();if(!o)return;let i=uk.resolve(t);o.includes(i)||(o.push(i),this.appendAuditLog({action:"grant-read",path:i,source:n,sessionId:r}))}addWriteRoot(t,n="slash",r){this.hooks.ensureInitialized?.();let o=this.hooks.getReadRoots(),i=this.hooks.getWriteRoots();if(!o||!i)return;let s=uk.resolve(t);o.includes(s)||o.push(s),i.includes(s)||(i.push(s),this.appendAuditLog({action:"grant-write",path:s,source:n,sessionId:r}))}revokeRoot(t,n="slash",r){let o=this.hooks.getReadRoots();if(!o)return;let i=uk.resolve(t),s=this.hooks.getProtectedRoot();if(s!==void 0&&i===s)return;let a=o.indexOf(i);a!==-1&&o.splice(a,1);let l=this.hooks.getWriteRoots();if(l){let c=l.indexOf(i);c!==-1&&l.splice(c,1)}this.appendAuditLog({action:"revoke",path:i,source:n,sessionId:r})}getGrants(){return{resolveBase:this.hooks.getProtectedRoot(),readRoots:this.hooks.getReadRoots()?.slice()??[],writeRoots:this.hooks.getWriteRoots()?.slice()??[],allowAll:this.hooks.getAllowAll()}}appendAuditLog(t){try{let n=_m();G9(W9(n),{recursive:!0});let r=JSON.stringify({timestamp:new Date().toISOString(),sessionId:t.sessionId??this.hooks.getDefaultSessionId?.()??null,action:t.action,path:t.path,source:t.source});K9(n,r+`
27
+ `),o+=Buffer.byteLength(d,"utf8");let p=s?d:`${v9(e)}${d}`;s=!0,l=l.then(async()=>{await h9(t,{recursive:!0,mode:448}),await g9(n,p,{encoding:"utf8",mode:384})}).catch(f=>{lt("subagent-output-capture",e.sessionId??"unknown","write",f)})},u=()=>{if(r.length===0)return;let d=r.join("").trim();r=[],d.length>0&&(c(Qm("say",{text:d})),a=!0)};return{observe(d){try{if(d.type==="chunk"){let p=d.chunk;if(p.type==="content"){r.push(p.content);return}if(p.type==="tool_use_detail"){if(p.pending)return;u(),c(Qm("tool",{toolName:p.toolName,toolInput:p.toolInputRaw??p.toolInput}))}return}if(d.type==="message"){if(!a&&r.length===0){let p=d.message.content.trim();p.length>0&&(c(Qm("say",{text:p})),a=!0)}return}(d.type==="done"||d.type==="error")&&(u(),a=!1)}catch(p){lt("subagent-output-capture",e.sessionId??"unknown","observe",p)}},end(d){try{u(),c(Qm("end",{reason:d}))}catch(p){lt("subagent-output-capture",e.sessionId??"unknown","end",p)}}}}var jP,HP,b9,GP=v(()=>{"use strict";W();G();Vm();Co();ek();jP=4*1024,HP=512*1024,b9="<!-- Best-effort secret redaction only. Connection strings, PEM blocks, and PII are NOT caught. -->"});async function Di(e,t){if(e)try{await e.write({kind:"tool_call",payload:t})}catch(n){lt("trace.emit",e,"tool_call",n)}}async function mn(e,t){if(e)try{await e.write({kind:"hook_decision",payload:t})}catch(n){lt("trace.emit",e,"hook_decision",n)}}async function Fi(e,t){if(e)try{await e.write({kind:"subagent_lifecycle",payload:t})}catch(n){lt("trace.emit",e,"subagent_lifecycle",n)}}async function Li(e,t){if(e)try{await e.write({kind:"background_agent",payload:t})}catch(n){lt("trace.emit",e,"background_agent",n)}}async function qP(e,t){if(e)try{await e.write({kind:"budget",payload:t})}catch(n){lt("trace.emit",e,"budget",n)}}async function zP(e,t){if(e)try{await e.write({kind:"abort",payload:t})}catch(n){lt("trace.emit",e,"abort",n)}}async function Zm(e,t){if(e)try{await e.write({kind:"compaction",payload:t})}catch(n){lt("trace.emit",e,"compaction",n)}}async function JP(e,t){if(e)try{await e.write({kind:"closure",payload:t})}catch(n){lt("trace.emit",e,"closure",n)}}async function ct(e,t){if(e)try{await e.write({kind:"browser_event",payload:t})}catch(n){lt("trace.emit",e,"browser_event",n)}}async function VP(e,t){if(e)try{await e.write({kind:"queued_user_message",payload:t})}catch(n){lt("trace.emit",e,"queued_user_message",n)}}async function re(e,t){if(e)try{await e.write({kind:"session_phase",payload:t})}catch(n){lt("trace.emit",e,"session_phase",n)}}var de=v(()=>{"use strict";Vm()});function YP(e){let t=[...e.oauthEntries??[],...e.effort?[e.effortEntry]:[],...e.extendedCacheTtl?[e.extendedCacheEntry]:[],...e.fast?[k9]:[]].filter(Boolean);return[...new Set(t)].join(",")||void 0}var k9,XP=v(()=>{"use strict";k9="fast-mode-2026-02-01"});function ef(e){return e.startsWith("sk-ant-oat01-")?"oauth":"api-key"}function mu(e,t,n,r){let o=t==="oauth"?{authToken:e}:{apiKey:e},i=typeof n=="string"&&n.length>0?{...o,baseURL:n}:o;return r?{...i,fetch:r}:i}function _o(e,t,n,r,o,i){let s=YP({oauthEntries:e==="oauth"?T9.split(","):[],effort:e==="oauth"&&r===!0,extendedCacheTtl:o,fast:i,effortEntry:E9,extendedCacheEntry:QP});return e!=="oauth"?s?{"anthropic-beta":s}:{}:{"anthropic-beta":s,"x-app":"cli","User-Agent":R9,"X-Claude-Code-Session-Id":t,"x-client-request-id":n}}function ZP(e){return e!=="oauth"?null:[{type:"text",text:x9}]}var QP,T9,E9,R9,x9,Ni=v(()=>{"use strict";XP();QP="extended-cache-ttl-2025-04-11",T9=`claude-code-20250219,oauth-2025-04-20,interleaved-thinking-2025-05-14,${QP}`,E9="effort-2025-11-24",R9="claude-cli/1.0.0 (external, cli)",x9="x-anthropic-billing-header: cc_version=1.0.0.test; cc_entrypoint=cli; cch=00000;"});function nf(e){ok=e}function tk(e){if(e===void 0)return;let t=e.trim();return t.length>0?t:void 0}function tf(e,t,n){let r={},o=tk(e);o&&(r.id=o);let i=tk(t);i&&(r.baseUrl=i);let s=tk(n);return s&&(r.apiKey=s),r}function A9(){return{local:tf(T.AFK_MODEL_LOCAL,T.AFK_MODEL_LOCAL_BASE_URL,T.AFK_MODEL_LOCAL_API_KEY),small:tf(T.AFK_MODEL_SMALL,T.AFK_MODEL_SMALL_BASE_URL,T.AFK_MODEL_SMALL_API_KEY),medium:tf(T.AFK_MODEL_MEDIUM,T.AFK_MODEL_MEDIUM_BASE_URL,T.AFK_MODEL_MEDIUM_API_KEY),large:tf(T.AFK_MODEL_LARGE,T.AFK_MODEL_LARGE_BASE_URL,T.AFK_MODEL_LARGE_API_KEY)}}function ak(e){let t=A9(),n={};for(let r of fu){let o=Bi[r],i=e?.[r],s=t[r],a={id:s.id??i?.id??o.id},l=i?.name;l&&(a.name=l);let c=i?.provider;c&&(a.provider=c);let u=s.baseUrl??i?.baseUrl;u&&(a.baseUrl=u);let d=s.apiKey??i?.apiKey;d&&(a.apiKey=d),n[r]=a}return n}function _a(e){return e||ok||ak()}function Ia(e,t=_a()){let n=e.trim().toLowerCase();if(!(!n||n===nM)){for(let r of fu){let o=t[r].name;if(o&&o.trim().toLowerCase()===n)return r}if(n==="local"||n==="small"||n==="medium"||n==="large")return n}}function Ui(e,t=_a()){if(e===void 0)return{id:""};let n=Ia(e,t);if(n)return t[n];let r=sk[e.trim().toLowerCase()];return r?{id:r}:{id:e}}function cr(e,t=_a()){if(e!==void 0)return Ui(e,t).id}function Pa(e,t=_a()){if(e===void 0)return;let n=Ia(e,t);if(n&&t[n].id.trim()===""){let r=n.toUpperCase();return`The "${n}" model tier is not configured (no model id). Set AFK_MODEL_${r}=<id> (optionally AFK_MODEL_${r}_BASE_URL / AFK_MODEL_${r}_API_KEY) or "models.${n}" in afk.config.json, then retry.`}}function rM(e){let t={};if(!e||typeof e!="object")return t;let n=e;for(let r of fu){let o=_9(n[r]);o&&(t[r]=o)}return t}function oM(e){if(typeof e!="string")return;let t=e.trim().toLowerCase();if(t==="anthropic"||t==="anthropic-direct")return"anthropic";if(t==="openai"||t==="openai-compatible")return"openai";if(t==="chatgpt-oauth"||t==="chatgpt")return"chatgpt-oauth"}function Ca(e){return typeof e=="string"?e.trim():""}function eM(e){return/[\x00-\x1f\x7f]/.test(e)}function _9(e){if(typeof e=="string"){let t=e.trim();return t?{id:t}:void 0}if(e&&typeof e=="object"){let t=e,n=Ca(t.id);if(!n)return;let r={id:n},o=Ca(t.name);o&&(r.name=o);let i=oM(t.provider);i&&(r.provider=i);let s=Ca(t.baseUrl);s&&(r.baseUrl=s);let a=Ca(t.apiKey);return a&&(r.apiKey=a),r}}function iM(e){if(!e||typeof e!="object"||Array.isArray(e))return{ok:!1,error:'model binding must be an object with at least an "id"'};let t=e;if("apiKey"in t||"api_key"in t)return{ok:!1,error:"per-slot API keys are credentials; set AFK_MODEL_<TIER>_API_KEY via `afk config env set` instead of afk.config.json"};if("baseUrl"in t||"base_url"in t)return{ok:!1,error:"per-slot baseUrl is an endpoint-redirect credential vector; set AFK_MODEL_<TIER>_BASE_URL via `afk config env set` instead of afk.config.json"};let n=Ca(t.id);if(!n)return{ok:!1,error:'model binding requires a non-empty "id"'};if(eM(n))return{ok:!1,error:'model binding "id" must not contain control characters'};let r={id:n},o=Ca(t.name);if(o){if(eM(o))return{ok:!1,error:'model binding "name" must not contain control characters'};if(C9.has(o.trim().toLowerCase()))return{ok:!1,error:`model binding "name" must not shadow a built-in alias ("${o}")`};r.name=o}if(t.provider!==void 0&&t.provider!==""){let i=oM(t.provider);if(!i)return{ok:!1,error:'model binding "provider" must be one of: anthropic, openai (aliases: anthropic-direct, openai-compatible)'};r.provider=i}return{ok:!0,value:r}}var fu,tM,nk,rk,ik,Bi,nM,sk,gu,ok,C9,Pt=v(()=>{"use strict";W();fu=["local","small","medium","large"],tM="claude-haiku-4-5-20251001",nk="claude-sonnet-4-6",rk="claude-opus-5",ik="claude-fable-5",Bi={local:{id:""},small:{id:tM},medium:{id:nk},large:{id:rk}},nM="auto",sk={opus:rk,opus_1m:rk,sonnet:nk,sonnet_1m:nk,haiku:tM,fable:ik},gu=[...fu,...Object.keys(sk)];C9=new Set([...fu,nM,...Object.keys(sk)])});function hu(e){return e in lk}function ht(e){return cr(e)}var lk,fn=v(()=>{"use strict";Pt();lk={opus:Bi.large.id,opus_1m:Bi.large.id,sonnet:Bi.medium.id,sonnet_1m:Bi.medium.id,haiku:Bi.small.id,fable:ik}});import I9 from"@anthropic-ai/sdk";import{randomUUID as sM}from"node:crypto";async function Ma(e){let{token:t,model:n,system:r,user:o,maxTokens:i=64,signal:s,clientFactory:a}=e;if(!t)throw new Error("oneShotCompletion: token required");let l=ef(t),c=mu(t,l),u=a?a(c):new I9(c),d=sM(),p=sM(),f=_o(l,d,p),g=ht(n)??n,h={};Object.keys(f).length>0&&(h.headers=f),s&&(h.signal=s);let y=await u.messages.create({model:g,max_tokens:i,system:r,messages:[{role:"user",content:o}]},Object.keys(h).length>0?h:void 0),b=[];for(let k of y.content)k.type==="text"&&b.push(k.text);let w=b.join("").trim();return w.length===0&&console.warn("oneShotCompletion: response contained no text blocks \u2014 returning empty string"),w}var rf=v(()=>{"use strict";Ni();fn()});function O9(){let e=T.AFK_VISION_MODELS,t=[],n=[];if(e)for(let r of e.split(",")){let o=r.trim().toLowerCase();if(o)if(o.startsWith("!")){let i=o.slice(1).trim();i&&n.push(i)}else t.push(o)}return{enable:t,disable:n}}function aM(e,t){return e===t||e.includes(t)}function of(e){if(!e)return!1;let t=(cr(e)??e).trim();if(!t)return!1;let n=t.toLowerCase(),{enable:r,disable:o}=O9();return o.some(i=>aM(n,i))?!1:r.some(i=>aM(n,i))||P9.has(n)?!0:M9.some(i=>i.test(t))}function lM(e){let t=e.trim().toLowerCase();return t.includes("/")?t.slice(t.lastIndexOf("/")+1):t}function ji(e){return e?/^o[0-9]/.test(lM(e)):!1}function yu(e){if(!e)return!1;if(ji(e))return!0;let t=lM(e);return $9.some(n=>n.test(t))}var P9,M9,$9,Hi=v(()=>{"use strict";W();Pt();P9=new Set(["gpt-4o","gpt-4o-mini","gpt-4.1","gpt-4.1-mini","gpt-4.1-nano","gpt-4-turbo","o1","o3","o4-mini"]),M9=[/^claude-/i,/^gpt-4o/i,/^gpt-4\.1/i,/^gpt-4-turbo/i,/^gpt-4-vision/i,/^gpt-5/i,/(?:^|[/_-])(?:vl|vlm)(?:[/_.-]|$)/i,/(?:^|[/_-])(?:llava|pixtral|internvl|cogvlm|idefics|moondream|janus)/i,/(?:vision|minicpm-?[vo]|qwen[\d.]*-?vl|llama-?3\.2-\d+b-vision|gemma-3|phi-3\.5-vision|phi-4-multimodal)/i];$9=[/^gpt-5/]});function ck(e){let t=String(e).trim().toLowerCase(),n=sf[t];if(t.endsWith("_1m")&&n!==void 0)return n;let r=cr(e)??String(e);return sf[r]??sf[r.toLowerCase()]}function bu(e){return ck(e)??D9}function N9(e){if(!e)return!1;let t=e.trim().toLowerCase();return t?!!(t.includes("/")||t.startsWith("gpt-")||t.startsWith("gpt_")||ji(t)||t.startsWith("codex-")||t.startsWith("codex_")||t==="codex"):!1}function Yt(e){let t=String(e).trim().toLowerCase(),n=Oa[t];if(t.endsWith("_1m")&&n!==void 0)return n;let r=cr(e)??String(e),o=Oa[r]??Oa[r.toLowerCase()];return o!==void 0?o:N9(r)?L9:F9}function Wi(e){let t=Yt(e);if(String(e).trim().toLowerCase().endsWith("_1m"))return t;let r=cr(e)??String(e),o=cM[r]??cM[r.toLowerCase()];return o!==void 0?Math.min(t,o):t}var sf,D9,Oa,F9,L9,cM,Io=v(()=>{"use strict";Pt();Hi();sf={opus:128e3,opus_1m:128e3,sonnet:128e3,sonnet_1m:128e3,haiku:64e3,fable:128e3,"claude-opus-5":128e3,"claude-opus-4-8":128e3,"claude-opus-4-7":128e3,"claude-opus-4-6":128e3,"claude-sonnet-5":128e3,"claude-sonnet-4-6":128e3,"claude-haiku-4-5-20251001":64e3,"claude-fable-5":128e3,"gpt-5.5":128e3,"gpt-5.6":128e3,"gpt-5.6-sol":128e3,"gpt-5.6-terra":128e3,"gpt-5.6-luna":128e3},D9=64e3;Oa={opus:1e6,opus_1m:1e6,sonnet:1e6,sonnet_1m:1e6,haiku:2e5,fable:1e6,"claude-fable-5":1e6,"claude-sonnet-5":1e6,"claude-opus-5":1e6,"claude-opus-4-8":1e6,"claude-opus-4-7":1e6,"claude-opus-4-6":1e6,"claude-sonnet-4-6":1e6,"gpt-4o":128e3,"gpt-4o-mini":128e3,"gpt-4.1":1e6,"gpt-4.1-mini":1e6,"gpt-5.5":1e6,"gpt-5.6":1e6,"gpt-5.6-sol":1e6,"gpt-5.6-terra":1e6,"gpt-5.6-luna":1e6,o1:2e5,"o1-mini":128e3,o3:2e5,"o3-mini":2e5,"o4-mini":2e5,"mlx-community/qwen3-30b-a3b-4bit":128e3,"mlx-community/qwen3-32b-4bit":128e3,"mlx-community/qwen2.5-coder-32b-instruct-4bit":131072},F9=2e5,L9=262144;cM={"claude-sonnet-5":2e5,"claude-opus-5":2e5,"claude-sonnet-4-6":2e5,"claude-opus-4-8":2e5,"claude-opus-4-7":2e5,"claude-opus-4-6":2e5}});function uM(e){return(e.inputTokens??0)+(e.outputTokens??0)}function Xt(e){return e.contextWindowTokens??uM(e)}function wu(e){return e?{totalTokens:Xt(e),apiUsage:{input_tokens:e.inputTokens??0,output_tokens:e.outputTokens??0,cache_read_input_tokens:e.cachedInputTokens??0,cache_creation_input_tokens:e.cacheCreationTokens??0,context_window_tokens:Xt(e)}}:{totalTokens:0,apiUsage:null}}function Su(e,t,n){return t<=0||e<=0||n<=0||n>=1?!1:e/t>=n}function vu(e,t){return t<=0||e<=0?0:e/t}function $a(e){if(e===void 0||e===!1)return;if(e===!0)return B9;let t=e.threshold;if(!(typeof t!="number"||!Number.isFinite(t)||t<=0||t>=1))return t}var B9,ku=v(()=>{"use strict";B9=.9});function lf(e,t){let n=bu(t),r=e.maxOutputTokens;if(typeof r=="number"&&Number.isFinite(r)&&r>0){let o=Math.floor(r);if(o>n){let i=`max:${t}:${o}`;return af.has(i)||(af.add(i),console.warn(`[afk] maxOutputTokens ${o} exceeds the ${t} output ceiling (${n}); clamping to ${n}.`)),n}return o}return n}function dM(e){if(!e||e.length===0)return;let t=[];for(let n of e)n.user.length>0&&t.push({role:"user",content:n.user}),n.assistant.length>0&&t.push({role:"assistant",content:n.assistant});return t.length>0?t:void 0}function cf(e,t,n){switch(e.type){case"adaptive":return{type:"adaptive",display:"summarized"};case"disabled":return{type:"disabled"};case"enabled":{if(typeof n=="string"&&j9(n))return{type:"adaptive",display:"summarized"};if(t<=1024)throw new Error(`[afk] Extended thinking requires max_tokens > 1024 (the API constraint is 1024 <= budget_tokens < max_tokens), but the resolved output cap is ${t}. Raise --max-output-tokens / AFK_MAX_OUTPUT_TOKENS above 1024, or disable thinking with --thinking disabled.`);let r=Math.floor(t*H9),o=Math.max(1024,t-1-r),i=e.budgetTokens!==void 0&&Number.isFinite(e.budgetTokens)?Math.floor(e.budgetTokens):void 0,s=Math.min(Math.max(i??o,1024),o);if(i!==void 0&&i>o){let a=`think:${n??"default"}:${i}:${t}`;af.has(a)||(af.add(a),console.warn(`[afk] thinking budgetTokens ${i} leaves too little of max_tokens ${t} for the reply; clamping to ${o}.`))}return{type:"enabled",budget_tokens:s,display:"summarized"}}}}function uf(e,t){if(e!==void 0)return e;let n=t.toLowerCase();if(/(claude-)?(opus|sonnet)-(4-[678]|5)/.test(n))return"max"}var U9,j9,af,H9,df=v(()=>{"use strict";Io();ku();U9=e=>/opus-4-(7|[89])/.test(e),j9=e=>U9(e)||/(claude-)?(opus|sonnet)-5/.test(e),af=new Set,H9=.25});import uk from"path";import{dirname as W9}from"path";import{appendFileSync as K9,mkdirSync as G9}from"fs";var Po,pf=v(()=>{"use strict";G();Po=class{hooks;constructor(t){this.hooks=t}addReadRoot(t,n="slash",r){this.hooks.ensureInitialized?.();let o=this.hooks.getReadRoots();if(!o)return;let i=uk.resolve(t);o.includes(i)||(o.push(i),this.appendAuditLog({action:"grant-read",path:i,source:n,sessionId:r}))}addWriteRoot(t,n="slash",r){this.hooks.ensureInitialized?.();let o=this.hooks.getReadRoots(),i=this.hooks.getWriteRoots();if(!o||!i)return;let s=uk.resolve(t);o.includes(s)||o.push(s),i.includes(s)||(i.push(s),this.appendAuditLog({action:"grant-write",path:s,source:n,sessionId:r}))}revokeRoot(t,n="slash",r){let o=this.hooks.getReadRoots();if(!o)return;let i=uk.resolve(t),s=this.hooks.getProtectedRoot();if(s!==void 0&&i===s)return;let a=o.indexOf(i);a!==-1&&o.splice(a,1);let l=this.hooks.getWriteRoots();if(l){let c=l.indexOf(i);c!==-1&&l.splice(c,1)}this.appendAuditLog({action:"revoke",path:i,source:n,sessionId:r})}getGrants(){return{resolveBase:this.hooks.getProtectedRoot(),readRoots:this.hooks.getReadRoots()?.slice()??[],writeRoots:this.hooks.getWriteRoots()?.slice()??[],allowAll:this.hooks.getAllowAll()}}appendAuditLog(t){try{let n=_m();G9(W9(n),{recursive:!0});let r=JSON.stringify({timestamp:new Date().toISOString(),sessionId:t.sessionId??this.hooks.getDefaultSessionId?.()??null,action:t.action,path:t.path,source:t.source});K9(n,r+`
28
28
  `)}catch{}}}});function Dn(e){return e==="bypassPermissions"||e==="autonomous"}var Da=v(()=>{"use strict"});var mf,pM=v(()=>{"use strict";pf();Da();mf=class{_readRoots;_writeRoots;_initialResolveBase;_currentCwd;_permissionMode="default";manager=new Po({getReadRoots:()=>this._readRoots,getWriteRoots:()=>this._writeRoots,ensureInitialized:()=>this.ensureInitialized(),getProtectedRoot:()=>this._initialResolveBase,getAllowAll:()=>Dn(this._permissionMode)});get readRoots(){return this._readRoots}get writeRoots(){return this._writeRoots}get currentCwd(){return this._currentCwd}set currentCwd(t){this._currentCwd=t}get permissionMode(){return this._permissionMode}set permissionMode(t){this._permissionMode=t}ensureInitialized(t){if(!this._readRoots){let n=t?[t]:[];this._readRoots=n.slice(),this._writeRoots=n.slice(),t&&!this._initialResolveBase&&(this._initialResolveBase=t),t&&!this._currentCwd&&(this._currentCwd=t)}}}});function Y9(e){return T[e]}function yM(e,t=!0){let n=Y9(e.key);if(n===void 0)return{...e,rawValue:n,effectiveValue:e.defaultValue,source:"default",valid:!0};let r=n.trim(),o=Number(r);return/^\d+$/.test(r)&&Number.isInteger(o)&&o>0&&o<=e.maxValue?{...e,rawValue:n,effectiveValue:o,source:"environment",valid:!0}:(t&&!mM.has(e.key)&&(mM.add(e.key),process.stderr.write(`[afk] Invalid ${e.key}=${JSON.stringify(n)}; using default ${e.defaultValue}. Expected an integer in [1, ${e.maxValue}].
29
29
  `)),{...e,rawValue:n,effectiveValue:e.defaultValue,source:"fallback",valid:!1})}function bM(e=!0){return hM.map(t=>yM(t,e))}function dk(e){let t=hM.find(n=>n.key===e);if(!t)throw new Error(`Unknown concurrency setting: ${e}`);return yM(t).effectiveValue}function wM(){return dk("AFK_MAX_CONCURRENT_SAFE_TOOL_CALLS")}function Tu(){return dk("AFK_MAX_CONCURRENT_SUBAGENT_CALLS")}function SM(){return dk("AFK_MAX_CONCURRENT_BACKGROUND_JOBS")}var fM,gM,q9,z9,J9,V9,hM,mM,Eu=v(()=>{"use strict";W();fM=8,gM=8,q9=10,z9=32,J9=32,V9=64,hM=[{key:"AFK_MAX_CONCURRENT_SAFE_TOOL_CALLS",defaultValue:fM,maxValue:z9},{key:"AFK_MAX_CONCURRENT_SUBAGENT_CALLS",defaultValue:gM,maxValue:J9},{key:"AFK_MAX_CONCURRENT_BACKGROUND_JOBS",defaultValue:q9,maxValue:V9}],mM=new Set});function pk(e){if(e instanceof st)return"timeout";if(e instanceof ar)return"budget";if(typeof e=="string"){if(e==="budget"||e.startsWith("Budget "))return"budget";if(e==="timeout"||e.includes("timed out"))return"timeout";if(e==="closed")return"closed"}return"interrupted"}function $t(e){let t=pk(e.reason);return t==="timeout"||t==="budget"?t:"abort"}var Ki=v(()=>{"use strict";Le()});async function Fa(e,t,n){let r=new Array(e.length),o=Math.min(Math.max(1,Math.floor(t)),e.length),i=0,s=[];for(let a=0;a<o;a++)s.push((async()=>{for(;i<e.length;){let l=i++;try{r[l]={status:"fulfilled",value:await n(e[l])}}catch(c){r[l]={status:"rejected",reason:c}}}})());return await Promise.all(s),r}var ff=v(()=>{"use strict";Eu()});function X9(e,t,n){return new Promise((r,o)=>{let i=!1,s=setTimeout(()=>{i||(i=!0,o(new ur(n,t)))},t);s.unref(),Promise.resolve(e).then(a=>{i||(i=!0,clearTimeout(s),r(a))},a=>{i||(i=!0,clearTimeout(s),o(a))})})}function Q9(e){return e.continue===!1||e.decision==="block"}function mk(e,t){if(e?.aborted){let n=e.reason,r=`aborted during ${t}${n?`: ${String(n)}`:""}`;throw new gt(r)}}function vM(){return new fk}var Gi,ur,fk,Ru=v(()=>{"use strict";Le();Gi=3e4;ur=class extends Error{constructor(n,r){super(`hook handler timed out after ${r}ms during ${n}`);this.hookEvent=n;this.timeoutMs=r;this.name="HookHandlerTimeoutError"}hookEvent;timeoutMs;code="HOOK_HANDLER_TIMEOUT"},fk=class{handlers=new Map;register(t,n,r={}){let o=this.handlers.get(t);o||(o=[],this.handlers.set(t,o));let i={handler:n,options:r};return o.push(i),()=>{let s=this.handlers.get(t);if(!s)return;let a=s.indexOf(i);a>=0&&s.splice(a,1)}}count(t){return this.handlers.get(t)?.length??0}async dispatch(t,n,r=Gi){mk(n,t.event);let o=this.handlers.get(t.event);if(!o||o.length===0)return{};let i=o.slice(),s={};for(let a of i){mk(n,t.event);let l;try{let u=a.handler(t,n);l=!a.options.longRunning&&r>0&&Number.isFinite(r)?await X9(u,r,t.event):await u}catch(u){throw u instanceof ur?u:new Re(`hook handler threw during ${t.event}`,t.event,u instanceof Error?u.message:String(u),{cause:u})}if(mk(n,t.event),Q9(l))throw new Re(`hook handler blocked ${t.event}${l.reason?`: ${l.reason}`:""}`,t.event,l.reason);let c=[s.injectContext,l.injectContext].filter(u=>typeof u=="string"&&u.length>0).join(`
30
30
  `);s={...s,...l,...c.length>0?{injectContext:c}:{}}}return s}}});async function dr(e,t,n,r){if(!e)return;if(r.kind==="blocked"){await mn(e,{hookEvent:t,decision:"block",...r.err.reason!==void 0?{reason:r.err.reason}:{},...t==="PreToolUse"&&n.toolName!==void 0?{blockedTool:n.toolName}:{}});return}let o=r.decision;await mn(e,{hookEvent:t,decision:o.decision,...o.reason!==void 0?{reason:o.reason}:{},...o.injectContext!==void 0?{injectedContextBytes:Buffer.byteLength(o.injectContext,"utf8")}:{}})}async function kM(e,t,n={}){if(e)try{let r=await e.dispatch(t,n.signal);await dr(n.traceWriter,"SubagentStart",{},{kind:"decision",decision:r})}catch(r){throw r instanceof Re&&await dr(n.traceWriter,"SubagentStart",{},{kind:"blocked",err:r}),r}}function Z9(e,t,n){return new Promise((r,o)=>{let i=!1,s=setTimeout(()=>{i||(i=!0,o(new ur(n,t)))},t);s.unref(),e.then(a=>{i||(i=!0,clearTimeout(s),r(a))},a=>{i||(i=!0,clearTimeout(s),o(a))})})}async function TM(e,t,n={}){if(!e)return{};try{let r=await Z9(e.dispatch(t,n.signal,Gi),Gi,"SubagentStop");return await dr(n.traceWriter,"SubagentStop",{},{kind:"decision",decision:r}),r}catch(r){return r instanceof ur?(console.warn(`[afk] SubagentStop hook timed out after ${Gi}ms (subagentId=${t.subagentId}): ${r.message}`),n.onError?.(r),{}):(r instanceof Re&&await dr(n.traceWriter,"SubagentStop",{},{kind:"blocked",err:r}),r instanceof Re||r instanceof gt?(U(`SubagentStop hook swallowed ${r.name}: ${r.message}`),n.onError?.(r),{}):(U(`SubagentStop hook unexpected error: ${String(r)}`),n.onError?.(r instanceof Error?r:new Error(String(r))),{}))}}async function EM(e,t,n={}){if(e)try{let r=await e.dispatch(t,n.signal);await dr(n.traceWriter,"PreToolUse",{toolName:t.toolName},{kind:"decision",decision:r})}catch(r){throw r instanceof Re&&await dr(n.traceWriter,"PreToolUse",{toolName:t.toolName},{kind:"blocked",err:r}),r}}async function RM(e,t,n={}){if(e)try{let r=await e.dispatch(t,n.signal);await dr(n.traceWriter,"PostToolUse",{toolName:t.toolName},{kind:"decision",decision:r})}catch(r){if(r instanceof Re&&await dr(n.traceWriter,"PostToolUse",{toolName:t.toolName},{kind:"blocked",err:r}),r instanceof Re||r instanceof gt){U(`PostToolUse hook swallowed ${r.name}: ${r.message}`),n.onError?.(r);return}U(`PostToolUse hook unexpected error: ${String(r)}`),n.onError?.(r instanceof Error?r:new Error(String(r)))}}async function xM(e,t,n={}){if(e)try{let r=await e.dispatch(t,n.signal);await dr(n.traceWriter,"PostToolUseFailure",{toolName:t.toolName},{kind:"decision",decision:r})}catch(r){if(r instanceof Re&&await dr(n.traceWriter,"PostToolUseFailure",{toolName:t.toolName},{kind:"blocked",err:r}),r instanceof Re||r instanceof gt){U(`PostToolUseFailure hook swallowed ${r.name}: ${r.message}`),n.onError?.(r);return}U(`PostToolUseFailure hook unexpected error: ${String(r)}`),n.onError?.(r instanceof Error?r:new Error(String(r)))}}var gf=v(()=>{"use strict";me();Le();Ru();de()});function AM(e,t){return t?.allowedTools?t.allowedTools.includes(e)?{allowed:!0}:{allowed:!1,reason:`Tool "${e}" is not in the configured allowlist`}:{allowed:!0}}function hf(e,t){return CM(e,t)}function yf(e,t){return CM(e,t)}function CM(e,t){if(!e?.allowedTools||t.length===0)return e;let n=new Set(e.allowedTools),r=!1;for(let o of t)n.has(o)||(n.add(o),r=!0);return r?{...e,allowedTools:[...n]}:e}var bf=v(()=>{"use strict"});function _Q(e){return e.replace(/'[^']*'/g," ").replace(/"(?:[^"\\]|\\.)*"/g,t=>/\$\(|`/.test(t)?t:" ")}function gk(e){return(e.split("/").pop()??e).replace(/^\\+/,"")}function IM(e){let t=[],n=[],r=[],o="",i=!1,s=()=>{i&&(r.push(o),o="",i=!1)},a=()=>{s(),r.length>0&&(t.push(r),r=[])},l=d=>{let p=d,f=1,g="";for(;p<e.length&&f>0;){let h=e[p];if(h==="(")f++;else if(h===")"&&(f--,f===0)){p++;break}g+=h,p++}return n.push(g),p},c=0,u=e.length;for(;c<u;){let d=e[c];if(d==="'"){for(i=!0,c++;c<u&&e[c]!=="'";)o+=e[c],c++;c++;continue}if(d==='"'){for(i=!0,c++;c<u&&e[c]!=='"';)if(e[c]==="$"&&e[c+1]==="(")c=l(c+2);else if(e[c]==="`"){c++;let p="";for(;c<u&&e[c]!=="`";)p+=e[c],c++;c++,n.push(p)}else o+=e[c],c++;c++;continue}if(d==="`"){s(),c++;let p="";for(;c<u&&e[c]!=="`";)p+=e[c],c++;c++,n.push(p);continue}if(d==="$"&&e[c+1]==="("){s(),c=l(c+2);continue}if(d===";"||d===`
@@ -267,7 +267,7 @@ ${o}`,paths:[t,n]}:o!==null?i={content:o,paths:[n]}:r!==null?i={content:r,paths:
267
267
 
268
268
  `).trim()}function gne(e){return(e?.textContent??"").replace(/\s+/g," ").trim().length}async function i$(e,t){let{JSDOM:n,Readability:r,turndown:o}=await fne(),s=new n(e,{url:t}).window.document,a=(s.title??"").trim(),l=(()=>{try{let p=s.cloneNode(!0);return new r(p).parse()}catch{return null}})();if(l&&typeof l.content=="string"&&l.content.trim().length>0){let p=o$(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:p,textLength:g,usedFallback:!1}}let c=s.body,u=c?.innerHTML??"",d=o$(o.turndown(u));return{title:a,markdown:d,textLength:gne(c),usedFallback:!0}}var TT,s$=v(()=>{"use strict";TT=null});function yne(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 a$(e,t,n){let r=Math.min(t*2**e,n);return Math.round(Math.random()*r)}function bne(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 l$(e,t,n={},r={}){let o=r.retries??3,i=r.baseDelayMs??500,s=r.maxDelayMs??1e4,a=r.sleep??yne,l=n.signal??void 0,c;for(let u=0;u<=o;u++){if(l?.aborted)throw l.reason??new Error("aborted");try{let d=await e(t,n);if(!hne.has(d.status)||u===o)return d;let p=bne(d,s)??a$(u,i,s);U("[web/retryFetch] retrying",{url:t,attempt:u,status:d.status,waitMs:p}),await d.body?.cancel().catch(()=>{}),await a(p,l)}catch(d){if(l?.aborted||(c=d,u===o))throw d;let p=a$(u,i,s);U("[web/retryFetch] retrying after error",{url:t,attempt:u,waitMs:p}),await a(p,l)}}throw c??new Error("retryFetch: exhausted without a result")}var hne,c$=v(()=>{"use strict";me();hne=new Set([429,502,503,504])});import{BlockList as wne,isIP as RT}from"node:net";import{lookup as Sne}from"node:dns/promises";import{Agent as vne}from"undici";function d$(){let e=T.AFK_WEB_ALLOW_PRIVATE_HOSTS?.trim().toLowerCase();return e==="1"||e==="true"}function Rne(e){return e.startsWith("[")&&e.endsWith("]")?e.slice(1,-1):e}function ET(e){let t=RT(e);return t===0?!1:Ene.check(e,t===4?"ipv4":"ipv6")}async function p$(e){return Sne(e,{all:!0,verbatim:!0})}async function xT(e,t={}){if(t.allowPrivateHosts??d$())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=Rne(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(RT(r)!==0)return ET(r)?{allowed:!1,reason:o(r,r)}:{allowed:!0};let i=t.lookupFn??p$,s;try{s=await i(r)}catch{return{allowed:!0}}for(let a of s)if(ET(a.address))return{allowed:!1,reason:o(a.address,`${r} (resolved)`)};return{allowed:!0}}async function Zu(e,t={}){let n=await xT(e,t);if(!n.allowed)throw new Bn(n.reason)}async function ug(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<=u$;s++){await Zu(i,o);let a={...n,redirect:"manual",...e===globalThis.fetch&&!(r.allowPrivateHosts??d$())?{dispatcher:xne}:{}},l=await l$(e,i,a,r.retry??{});if(!Ane.has(l.status))return l;let c=l.headers.get("location");if(c===null||c.trim()==="")return l;let u;try{u=new URL(c,l.url||i).toString()}catch{return l}await l.body?.cancel().catch(()=>{}),i=u}throw new Bn(`too many redirects (>${u$}) starting from ${t}`)}var kne,Tne,Ene,Bn,xne,u$,Ane,AT=v(()=>{"use strict";W();c$();kne=[["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]],Tne=[["::",96],["64:ff9b::",96],["fc00::",7],["fe80::",10]],Ene=(()=>{let e=new wne;for(let[t,n]of kne)e.addSubnet(t,n,"ipv4");for(let[t,n]of Tne)e.addSubnet(t,n,"ipv6");return e})(),Bn=class extends Error{constructor(t){super(t),this.name="EgressBlockedError"}};xne=new vne({connect:{lookup(e,t,n){p$(e).then(r=>{let o=r.find(s=>ET(s.address));if(o!==void 0){n(new Bn(`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,RT(i.address))},r=>n(r,"",0))}}});u$=20,Ane=new Set([301,302,303,307,308])});import{readFileSync as Cne}from"node:fs";import{join as _ne}from"path";function Ine(e){let n=e.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function m$(e,t){return Ine(t).test(e)}function One(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(Pne.has(t))return!0;if(Mne.has(t))return!1}return!1}function f$(e){return e===void 0||e.trim()===""?[]:e.split(",").map(t=>t.trim().toLowerCase()).filter(t=>t.length>0)}function $ne(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 g$(e){let t=e===void 0||e.trim()===""?"default":e.trim();return au(t),t}function Dne(e){if(e===void 0)return!1;let t=e.trim().toLowerCase();return t==="1"||t==="true"||t==="yes"}function Fne(e){try{return Cne(e,"utf8")}catch(t){if(t.code==="ENOENT")return;throw t}}function Lne(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=g$(t.defaultProfile)),n}function h$(e){let t=e?.env??T,n=e?.readFileSync??Fne,r=e?.surface??t.AGENT_SURFACE,o=One(t.AFK_BROWSER_HEADLESS,r),i=f$(t.AFK_BROWSER_ALLOWED_DOMAINS),s=f$(t.AFK_BROWSER_BLOCKED_DOMAINS),a=Dne(t.AFK_BROWSER_DOM_SNAPSHOTS),l=$ne(t.AFK_BROWSER_BACKEND),c=g$(t.AFK_BROWSER_DEFAULT_PROFILE),u={headless:o,allowedDomains:i,blockedDomains:s,domSnapshots:a,backend:l,configPath:null,defaultProfile:c},d=t.AFK_BROWSER_CONFIG,p=d!==void 0&&d.trim()!==""?d.trim():_ne($n(),"browser.json"),f=n(p);if(f===void 0)return u;let g;try{g=JSON.parse(f)}catch(y){throw new Error(`Failed to parse browser config at ${p}: ${String(y)}`)}if(typeof g!="object"||g===null||Array.isArray(g))throw new Error(`Browser config at ${p} must be a JSON object`);let h=Lne(u,g);return h.configPath=p,h}function dg(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(m$(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return t.allowedDomains.length>0&&!t.allowedDomains.some(o=>m$(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var Pne,Mne,pg=v(()=>{"use strict";W();G();Pne=new Set(["daemon","subagent","telegram","afk"]),Mne=new Set(["repl","interactive","cli"])});import{existsSync as Nne,readFileSync as Bne}from"node:fs";import{createRequire as Une}from"node:module";import{dirname as jne,join as Hne}from"node:path";function w$(e){if(typeof e=="string")return e;let t=[],n=e;for(let r=0;r<Kne&&n instanceof Error;r++)t.push(n.message),n=n.cause;return t.length>0?t.join(" | "):String(e)}function Ut(e){let t=w$(e);return b$.some(n=>t.includes(n))}function Gne(){try{let t=Une(import.meta.url).resolve("playwright/package.json"),n=JSON.parse(Bne(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=Hne(jne(t),o);return Nne(i)?`node ${/\s/.test(i)?`"${i}"`:i} install chromium`:void 0}catch{return}}function ed(){return y$??=Gne()??Wne,y$}function CT(e){return e.includes("install chromium")}function bn(e,t){let n=w$(e),r=t?.latched===!0?` ${qne}`:"";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: ${ed()}.${o}${r}`}return`browser tools require the optional \`playwright\` peer dependency. Install via: pnpm add playwright (then ${ed()}). Or pick a different tool.${r}`}function td(e,t,n=!1){if(!Ut(e))return e;let r=e instanceof Error?e.message:String(e);return new Error(`${r}
269
269
 
270
- ${bn(e,{headless:t,latched:n})}`,{cause:e})}var b$,Wne,Kne,y$,qne,mg=v(()=>{"use strict";b$=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],Wne="pnpm exec playwright install chromium",Kne=4;qne="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 os from"node:fs";import fg from"node:path";import{randomBytes as zne}from"node:crypto";import{chromium as Jne}from"playwright";function Vne(){try{return"5.106.0"}catch{}try{let e=fg.resolve(import.meta.dirname,"../../../package.json"),t=os.readFileSync(e,"utf8"),n=JSON.parse(t);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var Yne,gg,S$=v(()=>{"use strict";mg();G();me();Yne=Vne(),gg=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=Jne.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=td(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(p){throw i??p}if(i!==void 0)throw i;let c=await a.content();if(i!==void 0)throw i;let u=a.url(),d=l!==null?l.status():null;return{html:c,finalUrl:u,httpStatus:d}}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/${Yne}`}}loadStorageState(t){let n=lu(t);try{if(!os.existsSync(n))return;let r=JSON.parse(os.readFileSync(n,"utf8"));return U("[browser/vault] restored session",{profile:t,file:n}),r}catch(r){U("[browser/vault] ignoring unreadable vault",{profile:t,file:n,err:r});return}}async saveStorageState(t,n){try{let r=lu(t);if(!os.existsSync(r))return;let o=await n.storageState(),i=fg.join(fg.dirname(r),`.${fg.basename(r)}.${process.pid}.${zne(4).toString("hex")}.tmp`);os.writeFileSync(i,JSON.stringify(o),{mode:384}),os.chmodSync(i,384),os.renameSync(i,r),U("[browser/vault] saved session",{profile:t,file:r})}catch(r){U("[browser/vault] save failed",{profile:t,err:r})}}}});import{createHash as Xne}from"crypto";function v$(e){return!!(e.role==="textbox"&&e.kind==="password"||e.label&&Qne.test(e.label))}function k$(e){return Xne("sha256").update(e,"utf8").digest("hex").slice(0,8)}function T$(e){let t=e.replace(/\s+/g," ").trim();return t.length<=80?t:t.slice(0,77)+"..."}var Qne,hg=v(()=>{"use strict";Qne=/password|secret|token|api[_-]?key|otp|2fa/i});import{createHash as Zne}from"node:crypto";function ere(e){return e?e.replace(/\s+/g," ").trim().slice(0,200):""}function tre(e,t,n){return`el_${Zne("sha256").update(`${e}:${t}:${n}`).digest("hex").slice(0,6)}`}function nre(e){let t=e.replace(/\s+/g," ").trim(),n=4e3;return t.length<=n?t:t.slice(0,n)+"\u2026[truncated]"}function E$(e){return e.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function x$(e,t){let n=e.role??"",r=e.name??"";R$.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&t.push(e);for(let i of e.children??[])x$(i,t)}async function rre(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 u=window.getComputedStyle(s);if(u.display==="none"||u.visibility==="hidden")continue}let a=o.tagName.toLowerCase(),l=o.getAttribute("aria-label")??o.getAttribute("placeholder")??(o.textContent??"").replace(/\s+/g," ").trim().slice(0,100),c=a==="input"?o.type||null:o.getAttribute("type");r.push({name:l,tagName:a,type:c,id:o.id||null,testId:o.getAttribute("data-testid"),bbox:{x:Math.round(i.left),y:Math.round(i.top),w:Math.round(i.width),h:Math.round(i.height)}})}return r},A$).catch(()=>[])}async function ore(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 u="value"in i?i.value:void 0,d=u!==void 0?String(u):void 0,p=i.disabled??!1,f=s==="input"?i.checked:void 0,g={role:c,name:l,disabled:p};d!==void 0&&(g.value=d),f!==void 0&&(g.checked=f),o.push(g)}return o},A$).catch(()=>[])}function ire(e){let n=e.accessibility;return n!==null&&typeof n=="object"?n:null}async function yg(e,t){let n=t.maxElements??80,r=t.includeHidden??!1,o=[],i=ire(e),s=i?i.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=rre(e),l=e.evaluate(()=>document.body?.innerText??"").catch(()=>""),c=Promise.resolve(e.url()),u=e.title().catch(()=>""),[d,p,f,g,h]=await Promise.all([s,a,l,c,u]),y,b=!1;d!==null?(y=[],x$(d,y)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,y=(await ore(e)).filter(N=>R$.has(N.role??"")));let w=new Map;for(let P of p){let N=E$(P.name),q=w.get(N);(!q||q.bbox.w===0&&P.bbox.w>0)&&w.set(N,P)}let k=y.map(P=>({ax:P,dom:w.get(E$(P.name??""))})),S=r?k:k.filter(P=>P.dom?P.dom.bbox.w>0||P.dom.bbox.h>0:!0);S.sort((P,N)=>{let q=P.dom?.bbox.y??0,O=N.dom?.bbox.y??0;if(q!==O)return q-O;let H=P.dom?.bbox.x??0,K=N.dom?.bbox.x??0;return H-K}),S.length>200&&o.push("page has 200+ interactive elements; consider scoping");let x=S.slice(0,n).map((P,N)=>{let q=P.ax.role??"generic",O=P.ax.name??"",H=tre(q,O,N),K=P.dom?.bbox??{x:0,y:0,w:0,h:0},_=P.dom?.type??null,F=null;P.ax.value!==void 0&&P.ax.value!==null&&(F=String(P.ax.value)),P.ax.checked!==void 0&&(F=String(P.ax.checked)),v$({role:q,kind:_})&&(F="[redacted]");let M={disabled:P.ax.disabled??!1};P.ax.checked!==void 0&&(M.checked=P.ax.checked===!0||P.ax.checked==="mixed"),P.ax.selected!==void 0&&(M.selected=P.ax.selected),P.ax.expanded!==void 0&&(M.expanded=P.ax.expanded);let $;P.dom?.testId?$=`[data-testid="${P.dom.testId}"]`:P.dom?.id&&($=`#${P.dom.id}`);let B={id:H,role:q,label:ere(O),kind:_,value:F,state:M,bbox:K};return $!==void 0&&(B.selector=$),B}),D="idle";try{let P=await e.evaluate(()=>document.readyState);P==="loading"?D="loading":P==="interactive"?D="navigating":D="idle"}catch{D="navigating"}D!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),b&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let I=nre(f),A=`obs_${t.observationCounter.toString(36)}`,C=new Date().toISOString();return{observationId:A,url:g,title:h,textSummary:I,interactive:x,status:{httpStatus:t.httpStatus??null,loadingState:D,hasDialog:t.hasDialog??!1,consoleErrors:t.consoleErrors??0},warnings:o,screenshotPath:t.screenshotPath??null,capturedAt:C}}var R$,A$,C$=v(()=>{"use strict";hg();R$=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);A$="a[href], button, input, select, textarea, [role], [tabindex], label"});async function _$(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")??"",u=a.getBoundingClientRect();return{role:l,label:c,x:Math.round(u.x),y:Math.round(u.y),w:Math.round(u.width),h:Math.round(u.height)}}),r=`${n.role}:${n.label}:${t}`,o=0;for(let 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 _T(e,t){let n=Math.min(t,5);return(await Promise.all(Array.from({length:n},(o,i)=>_$(e,i)))).filter(o=>o!==null)}async function sre(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 IT(e,t,n){switch(t.kind){case"element_id":return are(e,t,n);case"selector":return lre(e,t);case"semantic":return cre(e,t)}}async function are(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 _T(o,i);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:s}}async function lre(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 _T(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${t.selector}]`},candidates:o}}async function cre(e,t){return t.role!==void 0?ure(e,t.text,t.role):dre(e,t.text,t)}async function ure(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 _T(r,o);return{outcome:"ambiguous_target",query:{text:t,role:n},candidates:i}}async function dre(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 u=[];s>0&&u.push({loc:r,count:s}),a>0&&u.push({loc:o,count:a}),l>0&&u.push({loc:i,count:l});let d=await sre(u);if(d.length===0)return{outcome:"not_found",query:n};if(d.length===1){let h=d[0];return h===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:h.locator.nth(h.index)}}let p=d.slice(0,5),f=[];for(let h=0;h<p.length;h++){let y=p[h];if(y===void 0)continue;let b=await _$(y.locator,y.index);if(b!==null){let w=`${b.role}:${b.label}:${h}`,k=0;for(let S=0;S<w.length;S++)k=k*31+w.charCodeAt(S)>>>0;f.push({...b,id:`el_${k.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:t},candidates:f}}var I$=v(()=>{"use strict"});async function PT(e,t,n,r){let o=e.url();if(o===n)return null;let i=dg(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 P$=v(()=>{"use strict";pg()});import{randomBytes as pre}from"crypto";import{mkdir as mre,stat as fre,writeFile as gre}from"fs/promises";import{join as MT}from"path";import{gzip as hre}from"zlib";import{promisify as yre}from"util";function bre(e){return MT(nr(e),"browser")}function wre(e){return MT(bre(e),"screenshots")}function Sre(){return new Date().toISOString().replace(/[:.]/g,"-")}function vre(){return pre(3).toString("hex")}async function OT(e,t,n){if(t.length>M$)throw new Error(`writeScreenshotSidecar: buffer exceeds ${M$} byte cap (received ${t.length} bytes). Refusing to write oversized screenshot.`);let r=wre(e);await mre(r,{recursive:!0});let o=`${Sre()}-${vre()}-${n}.png`,i=MT(r,o);await gre(i,t);let{size:s}=await fre(i);return{path:i,bytes:s}}var _je,M$,O$=v(()=>{"use strict";G();hg();_je=yre(hre);M$=5*1024*1024});var D$={};fa(D$,{PlaywrightProvider:()=>$T});function $$(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 $T,F$=v(()=>{"use strict";S$();C$();I$();pg();P$();O$();$T=class{name="playwright";config;launcher;sessions=new Map;constructor(t){this.config=t,this.launcher=new gg(t)}async open(t){let n=dg(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(d){a=d}let l=o.url();if(!(a!==null&&(l===""||l==="about:blank"))){let d=await PT(o,this.config,t.url,()=>this.close({sessionId:r}));if(d!==null)return d}(t.screenshot===!0||a!==null)&&(s=await this.captureScreenshot(o,r,"browser_open")),i.observationCounter+=1;let u=await yg(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,u.interactive,u.url,u.title,"browser_open"),a!==null)throw a;return u}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 yg(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 IT(r,t.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${$$(t.target)}`);if(a.outcome==="ambiguous_target")return a;let{locator:l}=a,c=null,u=async()=>{switch(t.action){case"click":await l.click({timeout: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 u()}catch(h){if(h instanceof Error&&/navigation|net::ERR/i.test(h.message))try{await u()}catch(y){c=y}else c=h}let d=await PT(r,this.config,i,()=>this.close({sessionId:n}));if(d!==null)return d;let p=null;(t.screenshot===!0||c!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await yg(r,{observationCounter:o.observationCounter,screenshotPath:p,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),g=`browser_act:${t.action}`;if(this.updateSessionFromObservation(o,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 u=await IT(r,t.target,o.knownElements);if(u.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${$$(t.target)}`);if(u.outcome==="ambiguous_target")throw new Error("screenshot target ambiguous; specify element_id or selector");i=await u.locator.screenshot()}else i=await r.screenshot({fullPage:t.fullPage??!1});let{path:s,bytes:a}=await OT(n,i,"browser_screenshot"),l=0,c=0;if(t.fullPage===!0)try{let u=await r.evaluate(()=>({w:document.documentElement.scrollWidth,h:document.documentElement.scrollHeight}));l=u.w,c=u.h}catch{let u=r.viewportSize();l=u?.width??0,c=u?.height??0}else{let u=r.viewportSize();l=u?.width??0,c=u?.height??0}return{path: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 OT(n,o,r);return i}catch{return null}}}});var ss={};fa(ss,{__resetBrowserRegistryForTests:()=>xre,browserProviderActive:()=>Ere,closeBrowserProvider:()=>DT,getBrowserProvider:()=>Tre,peekBrowserProvider:()=>Rre});function L$(){Promise.resolve(DT()).then(()=>{process.exit(130)})}function N$(){Promise.resolve(DT()).then(()=>{process.exit(143)})}function B$(){yr=null}function kre(){bg||(process.on("SIGINT",L$),process.on("SIGTERM",N$),process.on("exit",B$),bg=!0)}function U$(){bg&&(process.removeListener("SIGINT",L$),process.removeListener("SIGTERM",N$),process.removeListener("exit",B$),bg=!1)}async function Tre(e){return yr!==null?yr:(is!==null||(is=(async()=>{let{PlaywrightProvider:t}=await Promise.resolve().then(()=>(F$(),D$)),n=h$(e),r=new t(n);return kre(),yr=r,is=null,r})()),is)}async function DT(){if(yr===null)return;let e=yr;yr=null,is=null,U$(),await e.shutdown()}function Ere(){return yr!==null}function Rre(){return yr}function xre(){yr=null,is=null,U$()}var yr,is,bg,as=v(()=>{"use strict";pg();yr=null,is=null,bg=!1});async function j$(e,t){try{return await i$(e,t)}catch(n){return U("[web/scrape] extraction failed",{url:t,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function Mre(e,t){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(as(),ss));return(await n()).render({url:e,timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:t.requestGuard})}async function H$(e,t){let n=t.fetchFn??globalThis.fetch,r=t.renderFn??Mre,o=t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{},i=null,s=e,a=null,l=null;try{let u=await ug(n,e,{headers:Pre,signal:t.signal},o);a=u.status,s=u.url||e;let d=u.headers.get("content-type")??"";if(u.ok){if(Ire.test(d))throw new Error(`web_scrape markdown mode received binary content (${d.split(";")[0]}). Use mode: "raw" to fetch the bytes, or a different tool.`);let p=await u.text();if(_re.test(d)&&!Cre.test(d))return{title:"",markdown:p.trim(),finalUrl:s,usedRender:!1};if(i=await j$(p,s),t.signal.aborted)throw t.signal.reason??new Error("aborted")}}catch(u){if(t.signal.aborted||u instanceof Bn||u instanceof Error&&u.message.startsWith("web_scrape markdown mode received binary"))throw u;l=u}if(!(i===null||i.textLength<200)&&i!==null)return{title:i.title,markdown:i.markdown,finalUrl:s,usedRender:!1};try{await Zu(e,o);let u=await r(e,{timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:p=>Zu(p,o)});u.finalUrl!==e&&/^https?:\/\//i.test(u.finalUrl)&&await Zu(u.finalUrl,o);let d=await j$(u.html,u.finalUrl);if(t.signal.aborted)throw t.signal.reason??new Error("aborted");if(i===null||d.textLength>=i.textLength)return{title:d.title,markdown:d.markdown,finalUrl:u.finalUrl,usedRender:!0}}catch(u){if(t.signal.aborted||u instanceof Bn)throw u;if(i===null){let d=u instanceof Error?u.message:String(u),p=l instanceof Error?l.message:`HTTP ${a??"error"}`,f=new Error(`web_scrape could not retrieve ${e}: fetch failed (${p}) and render failed (${d}).`);throw f.cause=u,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 Cre,_re,Ire,Pre,W$=v(()=>{"use strict";s$();AT();me();Cre=/(text\/html|application\/xhtml\+xml)/i,_re=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,Ire=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,Pre={"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 Dre(e){let t=e.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let i=await t(Ore,{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),$re),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!i.ok){let l="";try{let u=await i.text(),d=bt(u);d&&(l=`: ${d.length>200?d.slice(0,200)+"\u2026":d}`)}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 K$(e){return e.exaApiKey!==void 0&&e.exaApiKey.trim()!==""?Dre({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 G$(e,t){if(t.length===0)return`# Search results for "${e}"
270
+ ${bn(e,{headless:t,latched:n})}`,{cause:e})}var b$,Wne,Kne,y$,qne,mg=v(()=>{"use strict";b$=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],Wne="pnpm exec playwright install chromium",Kne=4;qne="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 os from"node:fs";import fg from"node:path";import{randomBytes as zne}from"node:crypto";import{chromium as Jne}from"playwright";function Vne(){try{return"5.106.1"}catch{}try{let e=fg.resolve(import.meta.dirname,"../../../package.json"),t=os.readFileSync(e,"utf8"),n=JSON.parse(t);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var Yne,gg,S$=v(()=>{"use strict";mg();G();me();Yne=Vne(),gg=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=Jne.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=td(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(p){throw i??p}if(i!==void 0)throw i;let c=await a.content();if(i!==void 0)throw i;let u=a.url(),d=l!==null?l.status():null;return{html:c,finalUrl:u,httpStatus:d}}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/${Yne}`}}loadStorageState(t){let n=lu(t);try{if(!os.existsSync(n))return;let r=JSON.parse(os.readFileSync(n,"utf8"));return U("[browser/vault] restored session",{profile:t,file:n}),r}catch(r){U("[browser/vault] ignoring unreadable vault",{profile:t,file:n,err:r});return}}async saveStorageState(t,n){try{let r=lu(t);if(!os.existsSync(r))return;let o=await n.storageState(),i=fg.join(fg.dirname(r),`.${fg.basename(r)}.${process.pid}.${zne(4).toString("hex")}.tmp`);os.writeFileSync(i,JSON.stringify(o),{mode:384}),os.chmodSync(i,384),os.renameSync(i,r),U("[browser/vault] saved session",{profile:t,file:r})}catch(r){U("[browser/vault] save failed",{profile:t,err:r})}}}});import{createHash as Xne}from"crypto";function v$(e){return!!(e.role==="textbox"&&e.kind==="password"||e.label&&Qne.test(e.label))}function k$(e){return Xne("sha256").update(e,"utf8").digest("hex").slice(0,8)}function T$(e){let t=e.replace(/\s+/g," ").trim();return t.length<=80?t:t.slice(0,77)+"..."}var Qne,hg=v(()=>{"use strict";Qne=/password|secret|token|api[_-]?key|otp|2fa/i});import{createHash as Zne}from"node:crypto";function ere(e){return e?e.replace(/\s+/g," ").trim().slice(0,200):""}function tre(e,t,n){return`el_${Zne("sha256").update(`${e}:${t}:${n}`).digest("hex").slice(0,6)}`}function nre(e){let t=e.replace(/\s+/g," ").trim(),n=4e3;return t.length<=n?t:t.slice(0,n)+"\u2026[truncated]"}function E$(e){return e.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function x$(e,t){let n=e.role??"",r=e.name??"";R$.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&t.push(e);for(let i of e.children??[])x$(i,t)}async function rre(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 u=window.getComputedStyle(s);if(u.display==="none"||u.visibility==="hidden")continue}let a=o.tagName.toLowerCase(),l=o.getAttribute("aria-label")??o.getAttribute("placeholder")??(o.textContent??"").replace(/\s+/g," ").trim().slice(0,100),c=a==="input"?o.type||null:o.getAttribute("type");r.push({name:l,tagName:a,type:c,id:o.id||null,testId:o.getAttribute("data-testid"),bbox:{x:Math.round(i.left),y:Math.round(i.top),w:Math.round(i.width),h:Math.round(i.height)}})}return r},A$).catch(()=>[])}async function ore(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 u="value"in i?i.value:void 0,d=u!==void 0?String(u):void 0,p=i.disabled??!1,f=s==="input"?i.checked:void 0,g={role:c,name:l,disabled:p};d!==void 0&&(g.value=d),f!==void 0&&(g.checked=f),o.push(g)}return o},A$).catch(()=>[])}function ire(e){let n=e.accessibility;return n!==null&&typeof n=="object"?n:null}async function yg(e,t){let n=t.maxElements??80,r=t.includeHidden??!1,o=[],i=ire(e),s=i?i.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=rre(e),l=e.evaluate(()=>document.body?.innerText??"").catch(()=>""),c=Promise.resolve(e.url()),u=e.title().catch(()=>""),[d,p,f,g,h]=await Promise.all([s,a,l,c,u]),y,b=!1;d!==null?(y=[],x$(d,y)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,y=(await ore(e)).filter(N=>R$.has(N.role??"")));let w=new Map;for(let P of p){let N=E$(P.name),q=w.get(N);(!q||q.bbox.w===0&&P.bbox.w>0)&&w.set(N,P)}let k=y.map(P=>({ax:P,dom:w.get(E$(P.name??""))})),S=r?k:k.filter(P=>P.dom?P.dom.bbox.w>0||P.dom.bbox.h>0:!0);S.sort((P,N)=>{let q=P.dom?.bbox.y??0,O=N.dom?.bbox.y??0;if(q!==O)return q-O;let H=P.dom?.bbox.x??0,K=N.dom?.bbox.x??0;return H-K}),S.length>200&&o.push("page has 200+ interactive elements; consider scoping");let x=S.slice(0,n).map((P,N)=>{let q=P.ax.role??"generic",O=P.ax.name??"",H=tre(q,O,N),K=P.dom?.bbox??{x:0,y:0,w:0,h:0},_=P.dom?.type??null,F=null;P.ax.value!==void 0&&P.ax.value!==null&&(F=String(P.ax.value)),P.ax.checked!==void 0&&(F=String(P.ax.checked)),v$({role:q,kind:_})&&(F="[redacted]");let M={disabled:P.ax.disabled??!1};P.ax.checked!==void 0&&(M.checked=P.ax.checked===!0||P.ax.checked==="mixed"),P.ax.selected!==void 0&&(M.selected=P.ax.selected),P.ax.expanded!==void 0&&(M.expanded=P.ax.expanded);let $;P.dom?.testId?$=`[data-testid="${P.dom.testId}"]`:P.dom?.id&&($=`#${P.dom.id}`);let B={id:H,role:q,label:ere(O),kind:_,value:F,state:M,bbox:K};return $!==void 0&&(B.selector=$),B}),D="idle";try{let P=await e.evaluate(()=>document.readyState);P==="loading"?D="loading":P==="interactive"?D="navigating":D="idle"}catch{D="navigating"}D!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),b&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let I=nre(f),A=`obs_${t.observationCounter.toString(36)}`,C=new Date().toISOString();return{observationId:A,url:g,title:h,textSummary:I,interactive:x,status:{httpStatus:t.httpStatus??null,loadingState:D,hasDialog:t.hasDialog??!1,consoleErrors:t.consoleErrors??0},warnings:o,screenshotPath:t.screenshotPath??null,capturedAt:C}}var R$,A$,C$=v(()=>{"use strict";hg();R$=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);A$="a[href], button, input, select, textarea, [role], [tabindex], label"});async function _$(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")??"",u=a.getBoundingClientRect();return{role:l,label:c,x:Math.round(u.x),y:Math.round(u.y),w:Math.round(u.width),h:Math.round(u.height)}}),r=`${n.role}:${n.label}:${t}`,o=0;for(let 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 _T(e,t){let n=Math.min(t,5);return(await Promise.all(Array.from({length:n},(o,i)=>_$(e,i)))).filter(o=>o!==null)}async function sre(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 IT(e,t,n){switch(t.kind){case"element_id":return are(e,t,n);case"selector":return lre(e,t);case"semantic":return cre(e,t)}}async function are(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 _T(o,i);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:s}}async function lre(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 _T(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${t.selector}]`},candidates:o}}async function cre(e,t){return t.role!==void 0?ure(e,t.text,t.role):dre(e,t.text,t)}async function ure(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 _T(r,o);return{outcome:"ambiguous_target",query:{text:t,role:n},candidates:i}}async function dre(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 u=[];s>0&&u.push({loc:r,count:s}),a>0&&u.push({loc:o,count:a}),l>0&&u.push({loc:i,count:l});let d=await sre(u);if(d.length===0)return{outcome:"not_found",query:n};if(d.length===1){let h=d[0];return h===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:h.locator.nth(h.index)}}let p=d.slice(0,5),f=[];for(let h=0;h<p.length;h++){let y=p[h];if(y===void 0)continue;let b=await _$(y.locator,y.index);if(b!==null){let w=`${b.role}:${b.label}:${h}`,k=0;for(let S=0;S<w.length;S++)k=k*31+w.charCodeAt(S)>>>0;f.push({...b,id:`el_${k.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:t},candidates:f}}var I$=v(()=>{"use strict"});async function PT(e,t,n,r){let o=e.url();if(o===n)return null;let i=dg(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 P$=v(()=>{"use strict";pg()});import{randomBytes as pre}from"crypto";import{mkdir as mre,stat as fre,writeFile as gre}from"fs/promises";import{join as MT}from"path";import{gzip as hre}from"zlib";import{promisify as yre}from"util";function bre(e){return MT(nr(e),"browser")}function wre(e){return MT(bre(e),"screenshots")}function Sre(){return new Date().toISOString().replace(/[:.]/g,"-")}function vre(){return pre(3).toString("hex")}async function OT(e,t,n){if(t.length>M$)throw new Error(`writeScreenshotSidecar: buffer exceeds ${M$} byte cap (received ${t.length} bytes). Refusing to write oversized screenshot.`);let r=wre(e);await mre(r,{recursive:!0});let o=`${Sre()}-${vre()}-${n}.png`,i=MT(r,o);await gre(i,t);let{size:s}=await fre(i);return{path:i,bytes:s}}var _je,M$,O$=v(()=>{"use strict";G();hg();_je=yre(hre);M$=5*1024*1024});var D$={};fa(D$,{PlaywrightProvider:()=>$T});function $$(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 $T,F$=v(()=>{"use strict";S$();C$();I$();pg();P$();O$();$T=class{name="playwright";config;launcher;sessions=new Map;constructor(t){this.config=t,this.launcher=new gg(t)}async open(t){let n=dg(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(d){a=d}let l=o.url();if(!(a!==null&&(l===""||l==="about:blank"))){let d=await PT(o,this.config,t.url,()=>this.close({sessionId:r}));if(d!==null)return d}(t.screenshot===!0||a!==null)&&(s=await this.captureScreenshot(o,r,"browser_open")),i.observationCounter+=1;let u=await yg(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,u.interactive,u.url,u.title,"browser_open"),a!==null)throw a;return u}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 yg(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 IT(r,t.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${$$(t.target)}`);if(a.outcome==="ambiguous_target")return a;let{locator:l}=a,c=null,u=async()=>{switch(t.action){case"click":await l.click({timeout: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 u()}catch(h){if(h instanceof Error&&/navigation|net::ERR/i.test(h.message))try{await u()}catch(y){c=y}else c=h}let d=await PT(r,this.config,i,()=>this.close({sessionId:n}));if(d!==null)return d;let p=null;(t.screenshot===!0||c!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await yg(r,{observationCounter:o.observationCounter,screenshotPath:p,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),g=`browser_act:${t.action}`;if(this.updateSessionFromObservation(o,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 u=await IT(r,t.target,o.knownElements);if(u.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${$$(t.target)}`);if(u.outcome==="ambiguous_target")throw new Error("screenshot target ambiguous; specify element_id or selector");i=await u.locator.screenshot()}else i=await r.screenshot({fullPage:t.fullPage??!1});let{path:s,bytes:a}=await OT(n,i,"browser_screenshot"),l=0,c=0;if(t.fullPage===!0)try{let u=await r.evaluate(()=>({w:document.documentElement.scrollWidth,h:document.documentElement.scrollHeight}));l=u.w,c=u.h}catch{let u=r.viewportSize();l=u?.width??0,c=u?.height??0}else{let u=r.viewportSize();l=u?.width??0,c=u?.height??0}return{path: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 OT(n,o,r);return i}catch{return null}}}});var ss={};fa(ss,{__resetBrowserRegistryForTests:()=>xre,browserProviderActive:()=>Ere,closeBrowserProvider:()=>DT,getBrowserProvider:()=>Tre,peekBrowserProvider:()=>Rre});function L$(){Promise.resolve(DT()).then(()=>{process.exit(130)})}function N$(){Promise.resolve(DT()).then(()=>{process.exit(143)})}function B$(){yr=null}function kre(){bg||(process.on("SIGINT",L$),process.on("SIGTERM",N$),process.on("exit",B$),bg=!0)}function U$(){bg&&(process.removeListener("SIGINT",L$),process.removeListener("SIGTERM",N$),process.removeListener("exit",B$),bg=!1)}async function Tre(e){return yr!==null?yr:(is!==null||(is=(async()=>{let{PlaywrightProvider:t}=await Promise.resolve().then(()=>(F$(),D$)),n=h$(e),r=new t(n);return kre(),yr=r,is=null,r})()),is)}async function DT(){if(yr===null)return;let e=yr;yr=null,is=null,U$(),await e.shutdown()}function Ere(){return yr!==null}function Rre(){return yr}function xre(){yr=null,is=null,U$()}var yr,is,bg,as=v(()=>{"use strict";pg();yr=null,is=null,bg=!1});async function j$(e,t){try{return await i$(e,t)}catch(n){return U("[web/scrape] extraction failed",{url:t,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function Mre(e,t){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(as(),ss));return(await n()).render({url:e,timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:t.requestGuard})}async function H$(e,t){let n=t.fetchFn??globalThis.fetch,r=t.renderFn??Mre,o=t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{},i=null,s=e,a=null,l=null;try{let u=await ug(n,e,{headers:Pre,signal:t.signal},o);a=u.status,s=u.url||e;let d=u.headers.get("content-type")??"";if(u.ok){if(Ire.test(d))throw new Error(`web_scrape markdown mode received binary content (${d.split(";")[0]}). Use mode: "raw" to fetch the bytes, or a different tool.`);let p=await u.text();if(_re.test(d)&&!Cre.test(d))return{title:"",markdown:p.trim(),finalUrl:s,usedRender:!1};if(i=await j$(p,s),t.signal.aborted)throw t.signal.reason??new Error("aborted")}}catch(u){if(t.signal.aborted||u instanceof Bn||u instanceof Error&&u.message.startsWith("web_scrape markdown mode received binary"))throw u;l=u}if(!(i===null||i.textLength<200)&&i!==null)return{title:i.title,markdown:i.markdown,finalUrl:s,usedRender:!1};try{await Zu(e,o);let u=await r(e,{timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:p=>Zu(p,o)});u.finalUrl!==e&&/^https?:\/\//i.test(u.finalUrl)&&await Zu(u.finalUrl,o);let d=await j$(u.html,u.finalUrl);if(t.signal.aborted)throw t.signal.reason??new Error("aborted");if(i===null||d.textLength>=i.textLength)return{title:d.title,markdown:d.markdown,finalUrl:u.finalUrl,usedRender:!0}}catch(u){if(t.signal.aborted||u instanceof Bn)throw u;if(i===null){let d=u instanceof Error?u.message:String(u),p=l instanceof Error?l.message:`HTTP ${a??"error"}`,f=new Error(`web_scrape could not retrieve ${e}: fetch failed (${p}) and render failed (${d}).`);throw f.cause=u,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 Cre,_re,Ire,Pre,W$=v(()=>{"use strict";s$();AT();me();Cre=/(text\/html|application\/xhtml\+xml)/i,_re=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,Ire=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,Pre={"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 Dre(e){let t=e.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let i=await t(Ore,{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),$re),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!i.ok){let l="";try{let u=await i.text(),d=bt(u);d&&(l=`: ${d.length>200?d.slice(0,200)+"\u2026":d}`)}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 K$(e){return e.exaApiKey!==void 0&&e.exaApiKey.trim()!==""?Dre({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 G$(e,t){if(t.length===0)return`# Search results for "${e}"
271
271
 
272
272
  (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(`
273
273
  `).trimEnd()}var Ore,$re,q$=v(()=>{"use strict";Ur();Ore="https://api.exa.ai/search",$re=10});function wg(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 ls=v(()=>{"use strict";mg()});function jre(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=Fre;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,Lre)}let a=Nre;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,Bre)}return{mode:r,url:o,query:i,timeoutMs:s,maxBytes:a}}function FT(e,t){return Buffer.byteLength(e,"utf8")<=t?{content:e,truncated:!1}:{content:Br(e,t),truncated:!0}}function Hre(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=jre(o);if("error"in s)return{content:s.error,isError:!0};if(i.aborted){let d=i.reason;return{content:`web_scrape aborted: ${d instanceof Error?d.message:String(d??"aborted")}`,isError:!0}}let a=new AbortController,l=()=>{a.abort(i.reason)},c,u=()=>{let d=a.signal.reason;return d instanceof Error?d.message:String(d??"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 p=await xT(s.url,r);if(a.signal.aborted)return{content:`web_scrape aborted: ${u()}`,isError:!0};if(!p.allowed)return{content:`web_scrape blocked: ${p.reason}`,isError:!0}}if(s.mode==="raw"){let p;try{let h={method:"GET",headers:{"User-Agent":"agent-afk/web_scrape",Accept:"*/*"},signal:a.signal};p=await ug(t,s.url,h,r)}catch(h){return a.signal.aborted?{content:`web_scrape aborted: ${u()}`,isError:!0}:h instanceof Bn?{content:`web_scrape blocked: ${h.message}`,isError:!0}:{content:`web_scrape network error: ${h instanceof Error?h.message:String(h)}`,isError:!0}}if(!p.ok)return{content:`web_scrape HTTP ${p.status} ${p.statusText||""}`.trimEnd()+` for ${s.url}`,isError:!0};let f;try{f=await p.text()}catch(h){return{content:`web_scrape read error: ${h instanceof Error?h.message:String(h)}`,isError:!0}}let g=FT(f,s.maxBytes);return{content:g.content,...g.truncated?{truncated:!0}:{}}}if(s.mode==="markdown")try{let p=await H$(s.url,{fetchFn:t,renderFn:e.renderFn,timeoutMs:s.timeoutMs,signal:a.signal,...e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{}});if(p.markdown.trim().length===0)return{content:`web_scrape extracted no readable content from ${s.url}.`,isError:!0};let f=FT(p.markdown,s.maxBytes);return{content:f.content,...f.truncated?{truncated:!0}:{}}}catch(p){if(a.signal.aborted)return{content:`web_scrape aborted: ${u()}`,isError:!0};if(p instanceof Bn)return{content:`web_scrape blocked: ${p.message}`,isError:!0};let f=p instanceof Error?p.message:String(p),g=Ut(p)&&!CT(f)?` (the render fallback needs the optional Playwright browser \u2014 run \`${ed()}\`)`:"";return{content:`web_scrape markdown error: ${f}${g}`,isError:!0}}let d=K$({exaApiKey:n.EXA_API_KEY,fetchFn:t});if("error"in d)return{content:d.error,isError:!0};try{let p=await d.search(s.query,{limit:Ure,timeoutMs:s.timeoutMs,signal:a.signal}),f=FT(G$(s.query,p),s.maxBytes);return{content:f.content,...f.truncated?{truncated:!0}:{}}}catch(p){return a.signal.aborted?{content:`web_scrape aborted: ${u()}`,isError:!0}:{content:`web_scrape search error (${d.name}): ${p instanceof Error?p.message:String(p)}`,isError:!0}}}finally{c!==void 0&&clearTimeout(c),i.removeEventListener("abort",l)}}}var Fre,Lre,Nre,Bre,Ure,z$,J$=v(()=>{"use strict";W$();q$();AT();qi();ls();Fre=3e4,Lre=12e4,Nre=1e5,Bre=1e6,Ure=10;z$=Hre()});import{existsSync as Y$,mkdirSync as Wre,readFileSync as Kre,renameSync as Gre,unlinkSync as qre,writeFileSync as zre}from"node:fs";import{dirname as V$,join as Jre}from"node:path";import{randomBytes as Vre}from"node:crypto";function wn(e){let t=e??Av();if(!Y$(t))return[];try{let n=Kre(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 cs(e,t){let n=t??Av();Wre(V$(n),{recursive:!0});let r=Jre(V$(n),`.schedules.json.${process.pid}.${Vre(4).toString("hex")}.tmp`),o=JSON.stringify(e,null,2);try{zre(r,o,"utf-8"),Gre(r,n)}catch(i){try{Y$(r)&&qre(r)}catch{}throw i}}function Sg(e,t){let n=wn(t),r=n.map(l=>l.id),o=Yre(e.name),i=Xre(o,r),s=new Date().toISOString(),a={...e,notifyOn:e.notifyOn??"failure",id:i,createdAt:s,updatedAt:s};return n.push(a),cs(n,t),a}function vg(e,t){let n=wn(t),r=n.length,o=n.filter(i=>i.id!==e);return o.length===r?!1:(cs(o,t),!0)}function nd(e,t){return wn(t).find(n=>n.id===e)}function Yre(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"")}function Xre(e,t){if(!t.includes(e))return e;let n=2;for(;t.includes(`${e}-${n}`);)n+=1;return`${e}-${n}`}function X$(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 kg=v(()=>{"use strict";G()});import{existsSync as Qre,readFileSync as Zre}from"node:fs";import{join as eoe}from"node:path";async function Un(e,t,n){let r;try{let o=eoe(Pm("default"),"port");if(!Qre(o))return{synced:!1,detail:"daemon-not-detected (no port file)"};let i=Zre(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 Lo,LT=v(()=>{"use strict";G();Lo="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 toe}from"node:fs";import{readFile as noe}from"node:fs/promises";var Q$,Z$,eD,tD,nD=v(()=>{"use strict";kg();G();LT();Q$=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=Sg({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 Un("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 Un("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:Lo}})}},Z$=async(e,t)=>{let n=wn();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})))}},eD=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=tr();if(!toe(i))return{content:JSON.stringify([])};let s;try{let c=await noe(i);s=(c.length>1048576?c.subarray(c.length-1048576):c).toString("utf-8")}catch{return{content:JSON.stringify([])}}let a=s.split(`
@@ -1853,7 +1853,7 @@ ${S}
1853
1853
  ${E}`})}return{fileBlocks:l,warnings:c}}function NY(e){let t=e.replace(/\s+/g," ").trim();return t.length<=60?t:`${t.slice(0,59)}\u2026`}async function BY(e,t,n){let r=t?.peekQueuedText(),o=r!==void 0?{text:r.text,claimed:!1}:void 0;r!==void 0&&t?.reserveQueued?.(r);let i;try{i=await e.promoteActiveForeground(o)}catch(s){throw r!==void 0&&t?.releaseQueued?.(r),s}if(o?.claimed===!0&&t!==null&&r!==void 0){try{await n?.(o.text)}catch{}return t.dropQueued(r),{jobs:i,flushedText:o.text,flushedPreview:r.preview}}return r!==void 0&&t?.releaseQueued?.(r),{jobs:i}}async function UY(e,t,n,r,o="summary",i,s){let a=b2(e.text,e.attachments);r.onUserMessage&&await Promise.resolve(r.onUserMessage(a)).catch(()=>{}),r.setInFlight(!0),sc(process.stdout,pp(process.cwd(),!0));let l="",c=0,u=!1,d=!1,p=!1,f=!1,g=!1,h,y=!1,b=!1,w={abort:null},k=0,S=3e3,E=[],x=new Map,D=e.text.startsWith("/")?e.text.split(/[\s:]/)[0]?.slice(1):void 0,I=()=>{let O=r.subagentControl;O?.hasPromotableForeground()&&BY(O,A,r.onQueuedUserMessage).then(({jobs:H,flushedText:K,flushedPreview:_})=>{let F=(i??{fn:console.log}).fn;for(let M of H)F(m.dim(` \u2192 subagent backgrounded as ${M.jobId}: ${M.label}`));K!==void 0&&F(m.dim(` \u2192 queued message sent to this turn: ${NY(_??K)}`))}).catch(()=>{})},A=r.getCompositor?r.getCompositor():null,C=()=>new vc({out:kc(i),thinkingMode:o,...D?{activeSkillName:D}:{},onCancel:()=>{t.interrupt().catch(O=>{je()&&console.error(" "+m.error("session.interrupt() failed:"),O)})},...r.subagentControl?{onBackground:I}:{},...s?.history?{history:s.history}:{},...s?.autocompleteState?{autocompleteState:s.autocompleteState}:{},...s?.promptText!==void 0?{promptText:s.promptText}:{},...r.scrollRegion?{scrollRegion:r.scrollRegion}:{},...A?{compositor:A}:{},...r.onStageChange?{onStageChange:r.onStageChange}:{}}),P=C(),N=async()=>{if(!f){f=!0;try{await P.dispose()}catch{}}},q=async()=>{await P.arm();let O=P.getCompositor();if(i&&O){let H=O;i.fn=K=>H.commitAbove(K),i.suppressSubagentCompletion=!0}r.setActiveCompositor?.(O),r.setInterruptNotifier?.(H=>P.setInterrupting(H)),r.rearmStatus?.()};try{A?A.commitAbove(""):console.log(),r.setSoftStopHandler&&r.setSoftStopHandler(()=>{y=!0,P.setSoftStopping(!0),t.interrupt().catch($=>{je()&&console.error(" "+m.error("soft-stop session.interrupt() failed:"),$)});let M=r.subagentControl;M?.hasActiveForeground()&&M.cancelActiveForeground().catch($=>{je()&&console.error(" "+m.error("soft-stop cancelActiveForeground() failed:"),$)})}),r.setPauseInterruptHandler&&r.setPauseInterruptHandler(()=>{b=!0,t.interrupt().catch(M=>{je()&&console.error(" "+m.error("pause-interrupt session.interrupt() failed:"),M)})}),await q(),r.setBackgroundHandler&&r.subagentControl&&r.setBackgroundHandler(I);let{fileBlocks:O,warnings:H}=LY(e.text,{rootDir:process.cwd()});for(let M of H)(i??{fn:console.log}).fn(m.dim(` @-file: ${M}`));if(e.attachments.length>0&&(await t.waitForInitialization(),t.sessionId===void 0))throw new Error("CLI session initialized without a session id");let K=O.length>0||e.attachments.length>0?await FY(e.text,e.attachments,void 0,O,t.sessionId):e.text,_=t.sendMessageStream(K);if(await al((M,$)=>{P.process(M,$)},async()=>{for await(let M of _){if(y||b)break;if(M.type==="chunk"&&M.chunk.type==="content"?(l=u?$Y(l,M.chunk.content):l+M.chunk.content,u=!1,d=!0):M.type==="message"&&!d&&(l=M.message.content),M.type==="stream_retry"&&(l=l.slice(0,c),u=l.length>0),M.type==="chunk"&&M.chunk.type==="tool_use_detail"){let $=M.chunk,B={toolName:$.toolName,toolUseId:$.toolUseId,input:$.toolInput,...$.toolInputRaw!==void 0&&{inputRaw:$.toolInputRaw}};x.set($.toolUseId,B),E.push(B)}else if(M.type==="chunk"&&M.chunk.type==="tool_result"){let $=M.chunk;c=l.length,u=!0;let B=x.get($.toolUseId);if(B&&(B.result=$.content,B.isError=$.isError,x.delete($.toolUseId)),r.onContextProgress){let X=Date.now();if(X-k>=S){k=X;try{let j=r.onContextProgress();j instanceof Promise&&await j}catch(j){je()&&console.error(" "+m.error("onContextProgress (status refresh) failed:"),j)}}}}if(M.type==="paused"){if(r.setPausedState?.(!0),await N(),A&&M.autoResume===!0){let $=new AbortController;w.abort=$;let B=M.resetsAt?M.resetsAt.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit"}):null,X=B?`Keep waiting \u2014 auto-resumes at ${B}`:"Keep waiting \u2014 auto-resume in progress",j="Switch model / provider (type /model after)",ee="Stop waiting",se=[m.warning(" \u23F3 Usage limit reached.")+(B?m.dim(` Auto-resumes at ${B}.`):""),m.dim(" Tip: run `claude login` in another terminal to switch account \u2014 this turn resumes on it automatically."),""];Pn(A,{header:se,options:[X,j,ee],signal:$.signal,initialIndex:0}).then(z=>{if(w.abort=null,!z)return;let te=z[0];te===void 0||te===X||(b=!0,te===j&&(i??{fn:console.log}).fn(m.dim(" Hint: type /model <name> to switch, then send your message again.")),t.interrupt().catch(ae=>{je()&&console.error(" "+m.error("picker pause-interrupt session.interrupt() failed:"),ae)}))}).catch(z=>{je()&&console.error(" "+m.error("picker promise rejected:"),z)})}else(i??{fn:console.log}).fn(OP({reason:M.reason,...M.resetsAt!==void 0?{resetsAt:M.resetsAt}:{},...M.accountId!==void 0?{accountId:M.accountId}:{},...M.autoResume!==void 0?{autoResume:M.autoResume}:{}}));continue}if(M.type==="resumed"){r.setPausedState?.(!1),w.abort?.abort(),w.abort=null;let $=M.hotSwapped&&M.accountId?`\u25B6 Resumed on ${M.accountId}`:"\u25B6 Resumed";l="",c=0,u=!1,d=!1,E.length=0,x.clear(),g=!1,h=void 0,p=!1,P=C(),f=!1,await q(),(i??{fn:console.log}).fn(m.success($));continue}if(M.type==="error"){await N(),Aa(Sa(M.error)),p=!0;continue}P.process(M),M.type==="done"&&(g=!0,h=M.metadata)}}),await N(),y){let M=i?i.fn:console.log,$=A?A.getPendingCount():0,B=$>0?` \xB7 ${$} queued`:"";M(m.warning(`\u23F8 Stopped${B} \u2014 work so far kept.`)+m.dim(" Send a message to continue.")),M("")}if(b){let M=i?i.fn:console.log;M(m.dim("\u25B6 Ending wait \u2014 running your next command\u2026")),M("")}if(g&&!y&&!b){Ps(n,a,l,h,E),r.onTurnComplete&&await r.onTurnComplete(a,l).catch(()=>{}),ic(process.stdout),rG(process.stdout,"afk: turn complete");let M=B=>{i?i.fn(B):console.log(B)},$=kS(l);if($){M(DY($)),M("");let B=qz(E);if(r.onTerminalState)try{r.onTerminalState($,{doneHasCorroboratingEvidence:B})}catch{}if(n.permissionMode==="autonomous"){let X=$.kind==="done"&&Xu().verifyDone===!0&&!B;Jz($,void 0,{unverified:X})}}if(wEe(h,n,M),r.onAfterTurn){let B=r.onAfterTurn();B instanceof Promise&&await B.catch(()=>{})}}}catch(O){await N(),p||Aa(Sa(O))}finally{await N(),sc(process.stdout,pp(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),w.abort?.abort(),w.abort=null,r.setInFlight(!1),r.rearmStatus?.()}}function bEe(e,t){let n=Math.round(e*100),r=ye(t);if(e>=1){let o=Math.round((e-1)*t);return{tier:"over",text:` context OVER ${Math.round(t/1e3)}k tok by ~${ye(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 wEe(e,t,n=console.log){if(!e)return;let r=[];e.durationMs&&r.push(xe(e.durationMs)),e.totalCostUsd!==void 0&&r.push(ft(e.totalCostUsd));let o=Number(e.usage?.input_tokens??0),i=Number(e.usage?.output_tokens??0);o+i>0&&r.push(ye(o+i)+" tok"),r.length>0&&n(m.dim(" \u25E6 "+r.join(" \xB7 ")));let s=pC(t),a=Yt(t.model),l=bEe(s,a);if(l.text!==null){let u=l.tier==="over"||l.tier==="near"?m.error:l.tier==="caution"?m.warning:m.dim;n(u(l.text))}let c=OY(vw(rh()),new Date,{autoResume:YO()});if(c.text!==null){let u=c.tier==="over"||c.tier==="near"?m.error:c.tier==="caution"?m.warning:m.dim;n(u(c.text))}n("")}var SEe=5e3,vEe=3,kEe="[auto-resume] The background task above has finished. Continue the work it was dispatched for.";async function TEe(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(m.warning("\u26A0 ")+"first-turn hook failed: "+(r instanceof Error?r.message:String(r)))}}}async function jY(e,t,n,r,o,i,s,a){let{contextPane:l,loopStageBar:c,mascotBar:u,verdictLedger:d,shellPassthrough:p,bgResultNotifier:f}=s,g=null,h=[];e.session.current.waitForInitialization().then(async I=>{je()&&(g=Lw(I)),await Dp(e.session.current),h=cC()}).catch(()=>{});let y=e.initialInput!==void 0?{text:e.initialInput,attachments:[]}:void 0,b,w=!1,k=!1,S,E,x,D=0;for(f.onInjectable=()=>{D>=vEe||!o.isAwaitingInput()||!o.bufferIsEmpty()||(D++,ic(process.stdout),y={text:kEe,attachments:[]},o.abortPendingRead())};;){if(g&&(e.replRenderer.writeLine(g),e.replRenderer.writeLine(""),g=null),h.length>0){for(let _ of h)e.replRenderer.writeLine(_);e.replRenderer.writeLine(""),h=[]}let I=p.drainNotifications();for(let{job:_,result:F}of I){let M=F.errorReason===void 0?"\u2713":"\u2717",$=F.errorReason==="abort"?"killed":F.errorReason==="timeout"?"timed out":F.errorReason==="signal-killed"?"killed by signal":`exit ${F.exitCode??0}`,B=Math.max(0,Math.round(F.durationMs/100)/10);e.replRenderer.writeLine(m.dim(` ${M} [${_.id}] ${$} \xB7 ${B}s \xB7 `)+_.command)}let A=f.drainNotifications();for(let{job:_}of A){let F=_.status==="completed"?"\u2713":_.status==="failed"?"\u2717":"\u2298",M=_.endedAt!==void 0?Math.max(0,Math.round((_.endedAt-_.startedAt)/100)/10):0,$=le(_.label,60);e.replRenderer.writeLine(m.dim(` ${F} [${_.jobId}] subagent ${_.status} \xB7 ${M}s \xB7 `)+$)}let C=l.renderIfChanged(e.stats.sessionId);if(C.length>0){for(let _ of C)e.replRenderer.writeLine(_);e.replRenderer.writeLine("")}let P,N;if(y===void 0){let _=await e.session.current.takePendingPlanExitSeed();_!==void 0&&(e.stats.permissionMode=_.mode,y={text:_.message,attachments:[]})}if(y!==void 0){let _=y;y=void 0;let F=_c(e.stats.permissionMode),M=Fs({buffer:_.text,promptText:F,isTTY:!!process.stdout.isTTY,attachmentSummary:pc([..._.attachments])});e.replRenderer.writeLine(M),P=_.text.trim(),N=_.attachments}else{let _=b;b=void 0;let F=await o.readLine({promptFn:()=>_c(e.stats.permissionMode),..._!==void 0?{initialBuffer:_}:{},primePromptSuggestion:!0,onSigint:r,onShiftTab:()=>{yS(e.slashCtx).catch(()=>{}),e.statusLine.rearm()}});P=F.text.trim(),N=F.attachments}if(!P&&N.length===0)continue;if(P.startsWith("!")){let _=/^(0|false|off|no)$/i.test(T.AFK_SHELL_PASSTHROUGH??"");if(e.options.shellPassthrough!==!1&&!_&&(w||(w=!0,e.replRenderer.writeLine(m.dim(" \u2139 ! prefix shells out. Pass --no-shell-passthrough (or set AFK_SHELL_PASSTHROUGH=0) to send ! text to the model instead."))),await p.dispatch(P))){e.statusLine.rearm();continue}}let q=!1;if(P.startsWith("/")){let _=await sG(P,e.slashCtx,N);if(_.handled){if(_.result==="exit"){await e.resolveWorktreeDisposition?.(!0),e.rl.close();return}if((P==="/clear"||P.startsWith("/clear "))&&(await t.rotateOnClear(),e.replRenderer.writeLine(m.dim(` transcript: ${t.path()}`)),d.reset(),S=void 0),_.result!==null&&typeof _.result=="object"&&"kind"in _.result&&_.result.kind==="submit"){y={text:_.result.message,attachments:N??[]},e.statusLine.rearm();continue}if(_.result!==null&&typeof _.result=="object"&&"kind"in _.result&&_.result.kind==="prefill"){b=_.result.message,e.statusLine.rearm();continue}e.statusLine.rearm();continue}q=!0}a.push(P),await TEe(e,P);let O=P;if(q){let _=yA(P);if(_){let F=_.name.replace(/^\//,"").split(":").pop()??"";if(F&&iC(F)){let M={skillName:F,rawArgs:_.args,source:"plugin",capabilities:{compose:!0,subagents:!0}},$=e.session.current.sessionId,B=zs($),X=Date.now();U(`[afk trace] preflight.start commandName=${F}`);let j=!1,ee=await qs(M,{cwd:e.stats.cwd??process.cwd(),artifactDir:B},se=>{je()&&e.replRenderer.writeLine(m.warning(`\u26A0 preflight(${F}) failed: `)+(se instanceof Error?se.message:String(se)))});j=ee!==null,U(`[afk trace] preflight.end commandName=${F} durationMs=${Date.now()-X} success=${j}`),O=aC(ee?.manifestBlock,P)}}}let H=p.drainInjections();H.length>0&&(O=H+O);let K=f.drainInjections();if(K.length>0&&(O=K+O),S!==void 0&&(O=S+`
1854
1854
 
1855
1855
  `+O,S=void 0),e.hookRegistry)try{let _={event:"UserPromptSubmit",prompt:O,sessionId:e.stats.sessionId},F=await e.hookRegistry.dispatch(_);F.injectContext&&(O=F.injectContext+O)}catch(_){if(_ instanceof Re){e.replRenderer.writeLine(m.warning("\u2298 Turn blocked by hook")+(_.reason?m.dim(`: ${bt(_.reason)}`):"")),e.statusLine.rearm();continue}if(_ instanceof ur){e.replRenderer.writeLine(m.warning("\u2298 Turn blocked by hook")+m.dim(`: handler timed out after ${_.timeoutMs}ms`)),e.statusLine.rearm();continue}throw _}if(E=void 0,x=void 0,await UY({text:O,attachments:N},e.session.current,e.stats,{setInFlight(_){n.turnInFlight=_},...e.subagentControl?{subagentControl:e.subagentControl}:{},async onUserMessage(_){await t.appendUser(_)},async onQueuedUserMessage(_){await t.appendQueuedUser(_)},async onTurnComplete(_,F){if(await t.appendTurn(_,F),e.stats.sessionId)try{di(e.stats)}catch(M){k||(k=!0,e.replRenderer.writeLine(m.warning("\u26A0 ")+"session autosave failed \u2014 this conversation may not be resumable: "+(M instanceof Error?M.message:String(M))))}},async onAfterTurn(){await e.contextSampler.onTurn(e.stats.totalTurns),await e.gitStatusSampler.refresh(),e.statusLine.rearm(),c?.repaint("observing")},rearmStatus:()=>e.statusLine.rearm(),onTerminalState:(_,F)=>{d?.push(_),E=_.kind,x=F?.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(Xn(e.stats,e.contextSampler,e.gitStatusSampler))},...c?{onStageChange:(_,F)=>{c.repaint(_),u?.onStage(_,F)}}:{}},e.stats.thinkingUi??e.options.thinkingUi,e.completionWriter,o.toRunTurnRefs(_c(e.stats.permissionMode))),e.hookRegistry)try{let _=await e.hookRegistry.dispatch({event:"Stop",sessionId:e.stats.sessionId,...E!==void 0?{terminalState:E}:{},...x!==void 0?{doneHasCorroboratingEvidence:x}:{}},void 0,SEe);_.injectContext&&_.injectContext.trim().length>0&&(S=_.injectContext)}catch(_){if(_ instanceof gt)throw _;_ instanceof ur?(U("[stop hook] handler timed out"),e.completionWriter.fn(m.dim(" [stop hook] timed out"))):_ instanceof Re?e.completionWriter.fn(m.dim(` [stop hook] blocked: ${bt(_.reason??"no reason given")}`)):U("[stop hook] unexpected error: "+String(_))}}}function EEe(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 HY(e,t,n,r){let o=await cY(),i=new hS({rl:e.rl,history:o,statusLine:e.statusLine}),s=EEe(T.AFK_SUGGEST_GHOST,e.suggestGhostConfig),a;try{let{installSoftStop:l}=await fY(e,i,n,t,r,s,{getLoopStageBar:()=>a?.loopStageBar,getMascotBar:()=>a?.mascotBar});a=PY(e,n),await jY(e,t,n,r,i,l,a,o),await e.resolveWorktreeDisposition?.(!0)}finally{n.tryAbortShellForeground=null,a?.shellPassthrough.drainOnExit(),a?.bgResultNotifier.dispose(),a?.loopStageBar.stop(),a?.mascotBar.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)}}Wu();el();import{execFile as REe}from"node:child_process";import{dirname as xEe,isAbsolute as AEe,resolve as CEe}from"node:path";import{promisify as _Ee}from"node:util";var WY=_Ee(REe),IEe=3e3,PEe=new Set(["empty","orphaned-dir","orphaned-registration","dead-owner"]);async function MEe(){let t=(await WY("git",["rev-parse","--git-common-dir"])).stdout.trim();if(!t)throw new Error("Not in a git repository.");let n=AEe(t)?t:CEe(process.cwd(),t);return xEe(n)}async function KY(e){if(e?.disabled)return{ran:!1,removedCount:0,skippedReason:"disabled"};let t;try{t=await MEe()}catch{return{ran:!1,removedCount:0,skippedReason:"not-in-repo"}}let n,r=new Promise(o=>{n=setTimeout(()=>o("timeout"),IEe)});try{let o=vn({execFile:WY,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=>PEe.has(c.verdict)&&s.removed.includes(c.path)).length}}catch{return{ran:!1,removedCount:0,skippedReason:"error"}}finally{n&&clearTimeout(n)}}rf();Wu();import{promises as OEe}from"node:fs";import{dirname as $Ee,join as zY}from"node:path";import{randomBytes as DEe}from"node:crypto";var FEe=["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(`
1856
- `),GY=/^[a-z0-9]+(-[a-z0-9]+){1,3}$/,g_=30,LEe=1024,NEe=8e3,BEe="haiku";async function UEe(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=KEe(n,LEe),o=new AbortController,i=setTimeout(()=>o.abort(),t.timeoutMs??NEe),s=t.signal?GEe([t.signal,o.signal]):o.signal,a;try{t.slugGenerator?a=await t.slugGenerator(r,s):a=await Ma({token:t.token,model:t.model??BEe,system:FEe,user:r,maxTokens:32,signal:s})}catch(d){let p=d instanceof Error?d.message:String(d);return t.onSkip?.("slug-generator-error",p.slice(0,200)),null}finally{clearTimeout(i)}let l=jEe(a);if(l===null)return t.onSkip?.("invalid-slug-output",a.slice(0,60)),null;let c=$Ee(t.worktreePath);return await HEe(l,c)}function jEe(e){let t=e.trim().toLowerCase();if(t.length===0)return null;if(GY.test(t)&&t.length<=g_)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>g_)break;o=s}return GY.test(o)?o:null}async function HEe(e,t){if(!await WEe(zY(t,e)))return e;let n=DEe(2).toString("hex");return`${e.split("-").slice(0,3).join("-").slice(0,g_-5)}-${n}`}async function WEe(e){try{return await OEe.access(e),!0}catch{return!1}}function KEe(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 GEe(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 JY(e){let t,n,r=zY(e.deferred.repoRoot,".afk-worktrees","unnamed"),o=await UEe(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=`${ng(e.branchPrefix)}${o}`;try{let c=await e.deferred.create(l);return qY(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 qY(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 qY(e,t){e&&e.setCwd(t),qEe(t)}function qEe(e){try{process.chdir(e)}catch{}}nt();wt();G();import{spawn as YY}from"child_process";import{existsSync as XY,mkdirSync as XEe,readFileSync as QY,unlinkSync as VY,writeFileSync as ZY}from"fs";import{get as QEe}from"https";import{join as e4}from"path";import{readFileSync as zEe}from"fs";import{dirname as JEe,join as VEe}from"path";import{fileURLToPath as YEe}from"url";function Pr(){try{return"5.106.0"}catch{}try{let e=JEe(YEe(import.meta.url));for(let t of["../../package.json","../package.json"])try{let n=JSON.parse(zEe(VEe(e,t),"utf-8"));if(typeof n.version=="string")return n.version}catch{}}catch{}return"0.0.0-unknown"}W();var ZEe=64*1024,eRe=10800*1e3,tRe=800,nRe=3600*1e3,rRe="update-check.json",oRe="pending-update.json";function h_(){return e4(ya(),rRe)}function zp(){return e4(ya(),oRe)}function y_(){let e=ya();XY(e)||XEe(e,{recursive:!0})}function t4(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 n4(){try{let e=QY(h_(),"utf-8"),t=JSON.parse(e);if(typeof t.latestVersion=="string"&&typeof t.checkedAt=="number")return t}catch{}return null}function r4(){try{y_();let e=`
1856
+ `),GY=/^[a-z0-9]+(-[a-z0-9]+){1,3}$/,g_=30,LEe=1024,NEe=8e3,BEe="haiku";async function UEe(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=KEe(n,LEe),o=new AbortController,i=setTimeout(()=>o.abort(),t.timeoutMs??NEe),s=t.signal?GEe([t.signal,o.signal]):o.signal,a;try{t.slugGenerator?a=await t.slugGenerator(r,s):a=await Ma({token:t.token,model:t.model??BEe,system:FEe,user:r,maxTokens:32,signal:s})}catch(d){let p=d instanceof Error?d.message:String(d);return t.onSkip?.("slug-generator-error",p.slice(0,200)),null}finally{clearTimeout(i)}let l=jEe(a);if(l===null)return t.onSkip?.("invalid-slug-output",a.slice(0,60)),null;let c=$Ee(t.worktreePath);return await HEe(l,c)}function jEe(e){let t=e.trim().toLowerCase();if(t.length===0)return null;if(GY.test(t)&&t.length<=g_)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>g_)break;o=s}return GY.test(o)?o:null}async function HEe(e,t){if(!await WEe(zY(t,e)))return e;let n=DEe(2).toString("hex");return`${e.split("-").slice(0,3).join("-").slice(0,g_-5)}-${n}`}async function WEe(e){try{return await OEe.access(e),!0}catch{return!1}}function KEe(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 GEe(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 JY(e){let t,n,r=zY(e.deferred.repoRoot,".afk-worktrees","unnamed"),o=await UEe(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=`${ng(e.branchPrefix)}${o}`;try{let c=await e.deferred.create(l);return qY(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 qY(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 qY(e,t){e&&e.setCwd(t),qEe(t)}function qEe(e){try{process.chdir(e)}catch{}}nt();wt();G();import{spawn as YY}from"child_process";import{existsSync as XY,mkdirSync as XEe,readFileSync as QY,unlinkSync as VY,writeFileSync as ZY}from"fs";import{get as QEe}from"https";import{join as e4}from"path";import{readFileSync as zEe}from"fs";import{dirname as JEe,join as VEe}from"path";import{fileURLToPath as YEe}from"url";function Pr(){try{return"5.106.1"}catch{}try{let e=JEe(YEe(import.meta.url));for(let t of["../../package.json","../package.json"])try{let n=JSON.parse(zEe(VEe(e,t),"utf-8"));if(typeof n.version=="string")return n.version}catch{}}catch{}return"0.0.0-unknown"}W();var ZEe=64*1024,eRe=10800*1e3,tRe=800,nRe=3600*1e3,rRe="update-check.json",oRe="pending-update.json";function h_(){return e4(ya(),rRe)}function zp(){return e4(ya(),oRe)}function y_(){let e=ya();XY(e)||XEe(e,{recursive:!0})}function t4(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 n4(){try{let e=QY(h_(),"utf-8"),t=JSON.parse(e);if(typeof t.latestVersion=="string"&&typeof t.checkedAt=="number")return t}catch{}return null}function r4(){try{y_();let e=`
1857
1857
  const https = require('https');
1858
1858
  const fs = require('fs');
1859
1859
  const url = 'https://registry.npmjs.org/agent-afk/latest';
@@ -2020,19 +2020,19 @@ Multiple chats found:`)),o.forEach((l,c)=>{let u=l.username?`@${l.username}`:l.f
2020
2020
  `))})}function SAe(e){if(console.log(m.heading("\u{1F4CA} Telegram Bot Status")),console.log(""),e.running?(console.log(` ${m.success("\u25CF")} Running (PID ${e.pid})`),e.uptimeSec!==void 0&&console.log(` Uptime: ${vAe(e.uptimeSec)}`),e.memoryMb!==void 0&&console.log(` Memory: ${e.memoryMb} MB`)):console.log(` ${m.error("\u25CF")} Stopped`),console.log(` PID: ${e.pidFile}`),console.log(` Logs: ${e.logFile}`),e.logTail&&e.logTail.length>0){console.log(""),console.log(m.heading("Recent log entries:"));for(let t of e.logTail)console.log(m.meta(` ${t}`))}}function vAe(e){if(e<60)return`${e}s`;let t=Math.floor(e/60);if(t<60)return`${t}m ${e%60}s`;let n=Math.floor(t/60);return n<24?`${n}h ${t%60}m`:`${Math.floor(n/24)}d ${n%24}h`}import{execFile as YAe}from"node:child_process";import{promisify as XAe}from"node:util";G();import{execFile as kAe}from"node:child_process";import{randomBytes as TAe}from"node:crypto";import{promises as $c}from"node:fs";import{join as US}from"node:path";import{promisify as EAe}from"node:util";var RAe=EAe(kAe),K8=16;var Ot=class extends Error{cause;code;constructor(t,n,r){super(t),this.name="WorktreeError",this.cause=n,this.code=r}};function K_(e,t=40){return e.toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,t).replace(/-+$/g,"")||"task"}function xAe(){return TAe(4).toString("hex").slice(0,4)}function AAe(e){let t=n=>String(n).padStart(2,"0");return`${e.getUTCFullYear()}${t(e.getUTCMonth()+1)}${t(e.getUTCDate())}T${t(e.getUTCHours())}${t(e.getUTCMinutes())}${t(e.getUTCSeconds())}`}function CAe(e,t={}){let n=(t.now??(()=>new Date))(),r=(t.randomSuffix??xAe)();return`${AAe(n)}-${K_(e,32)}-${r}`}async function ia(e,t){try{let n=await RAe("git",t,{cwd:e,maxBuffer:4194304});return{stdout:n.stdout.trim(),stderr:n.stderr.trim()}}catch(n){let r=n,o=(r.stderr??r.stdout??r.message??"").toString().trim();throw new Ot(`git ${t.join(" ")} failed: ${o}`,n)}}async function _Ae(e){let{stdout:t}=await ia(e,["rev-parse","--show-toplevel"]);if(!t)throw new Ot(`not a git repository: ${e}`);return t}async function IAe(e,t){if(t){let{stdout:o}=await ia(e,["rev-parse",t]);return{sha:o}}let{stdout:n}=await ia(e,["rev-parse","HEAD"]),r;try{let{stdout:o}=await ia(e,["symbolic-ref","--quiet","HEAD"]);o&&(r=o)}catch{}return{sha:n,branch:r}}function PAe(e,t,n){let r=n?K_(n,32):`branch-${t}`;return`afk/farm/${e}/${t}-${r}`}function MAe(e,t){return US(e,`branch-${t}`)}async function OAe(e,t){try{await ia(e,["worktree","remove","--force",t])}catch{}}async function $Ae(e,t){try{await ia(e,["branch","-D",t])}catch{}}async function G8(e){if(e.count<1||e.count>K8)throw new Ot(`count must be between 1 and ${K8}, got ${e.count}`);if(e.labels&&e.labels.length!==e.count)throw new Ot(`labels.length (${e.labels.length}) must equal count (${e.count})`);let t=e.cwd??process.cwd(),n=await _Ae(t),{sha:r,branch:o}=await IAe(n,e.baseRef),i=(e.now??(()=>new Date))(),s=e.taskSlug??CAe(e.taskName,{now:()=>i,randomSuffix:e.randomSuffix}),a=e.taskSlug??s,l=_v(s);try{throw await $c.access(l),new Ot(`farm directory already exists: ${l}`)}catch(d){if(d.code!=="ENOENT")throw d instanceof Ot?d:new Ot(`failed to check farm dir ${l}`,d)}await $c.mkdir(l,{recursive:!0});let c=[];try{for(let d=1;d<=e.count;d++){let p=e.labels?.[d-1],f=PAe(s,d,p),g=MAe(l,d);await ia(n,["worktree","add","-b",f,g,r]),c.push({index:d,label:p?K_(p,32):void 0,path:g,branch:f})}}catch(d){for(let p of c.slice().reverse())await OAe(n,p.path),await $Ae(n,p.branch);throw await $c.rm(l,{recursive:!0,force:!0}).catch(()=>{}),d instanceof Ot?d:new Ot("farm creation failed",d)}let u={schemaVersion:3,taskId:a,taskSlug:s,taskName:e.taskName,repoRoot:n,baseRef:r,baseBranch:o,farmDir:l,createdAt:i.toISOString(),branches:c};return await $c.writeFile(US(l,"farm.json"),JSON.stringify(u,null,2)+`
2021
2021
  `,"utf8"),u}function DAe(e){let t=e;return t.respawnedAt===void 0&&(t.respawnedAt=void 0),t.respawnedAs===void 0&&(t.respawnedAs=void 0),t.prUrl===void 0&&(t.prUrl=void 0),t.prCreatedAt===void 0&&(t.prCreatedAt=void 0),t}async function FAe(e){let t=US(_v(e),"farm.json");try{let n=await $c.readFile(t,"utf8"),r=JSON.parse(n);if(r.schemaVersion!==1&&r.schemaVersion!==2&&r.schemaVersion!==3)throw new Ot(`unsupported farm manifest schema: ${r.schemaVersion} (expected 1, 2, or 3)`,void 0,"unsupported-schema");return DAe(r)}catch(n){if(n.code==="ENOENT")return null;throw n instanceof Ot?n:new Ot(`failed to load farm manifest ${t}`,n,"invalid")}}async function q8(e,t){let n=await FAe(e);if(!n)throw new Ot(`farm not found: ${e}`);return n.memoryFactId=t,n.schemaVersion=3,await $c.writeFile(US(n.farmDir,"farm.json"),JSON.stringify(n,null,2)+`
2022
2022
  `,"utf8"),n}jx();et();nt();import{spawn as LAe}from"child_process";import{promises as jS}from"fs";import{join as nm,dirname as Q_t}from"path";var NAe=1,HS=12e4;async function Y8(e){let{branchPath:t,baseSha:n,testCmd:r,timeoutMs:o=HS,_spawn:i=LAe,_readPackageJson:s=BAe,_now:a=Date.now,_nowIso:l=()=>new Date().toISOString()}=e,c=r??await UAe(t,s),u=0,d=0,p=0,f;if(c){let b=await Q8(c,t,o,i,a);p=b.durationMs,b.timedOut?(d=1,f=`tests timed out after ${o}ms`):b.crashed?(d=1,f=`test runner crashed: ${WAe(b.stderr,200)}`):b.exitCode===0?u=1:d=1}else f="no test command found (no package.json scripts.test)";let g=await jAe(t,o,i,a),h=await HAe(t,n,i),y={schemaVersion:NAe,pass:u,fail:d,loc_delta:h,lint_ok:g,duration_ms:p,branchPath:t,baseSha:n,scoredAt:l()};return f!==void 0&&(y.error=f),c!==void 0&&(y.testCmd=c),y}async function X8(e,t,n){let r=nm(e,"scores");await jS.mkdir(r,{recursive:!0});let o=nm(r,`branch-${t}.json`);return await jS.writeFile(o,JSON.stringify(n,null,2)+`
2023
- `,"utf8"),o}function rm(e){let t=e.filter(r=>r.score!==null),n=e.filter(r=>r.score===null).map(r=>r.index).sort((r,o)=>r-o);return t.sort((r,o)=>{let i=r.score,s=o.score,a=z8(i),l=z8(s);if(a!==l)return l-a;let c=J8(i.lint_ok),u=J8(s.lint_ok);return c!==u?u-c:i.loc_delta!==s.loc_delta?i.loc_delta-s.loc_delta:r.index-o.index}),[...t.map(r=>r.index),...n]}async function BAe(e){try{let t=await jS.readFile(e,"utf8");return JSON.parse(t)}catch{return null}}async function UAe(e,t){let n=await t(nm(e,"package.json"));if(!V8(n))return;let r=n.scripts;return!V8(r)||typeof r.test!="string"?void 0:await Z8(nm(e,"pnpm-lock.yaml"))?"pnpm test":"npm test"}async function Q8(e,t,n,r,o){let i=o();return new Promise(s=>{let a;try{a=r(e,{cwd:t,shell:!0,stdio:["ignore","pipe","pipe"],env:{...process.env,CI:"1"}})}catch(p){s({exitCode:null,durationMs:o()-i,stderr:p instanceof Error?p.message:String(p),timedOut:!1,crashed:!0});return}let l="",c=!1,u=!1,d=setTimeout(()=>{c=!0,a.kill("SIGKILL")},n);a.stderr?.on("data",p=>{l+=String(p),l.length>64e3&&(l=l.slice(-32e3))}),a.on("error",p=>{u||(u=!0,clearTimeout(d),s({exitCode:null,durationMs:o()-i,stderr:p.message,timedOut:!1,crashed:!0}))}),a.on("close",p=>{u||(u=!0,clearTimeout(d),s({exitCode:p,durationMs:o()-i,stderr:l,timedOut:c,crashed:!1}))})})}async function jAe(e,t,n,r){if(!await Z8(nm(e,"tsconfig.json")))return null;let o=await Q8("npx --no-install tsc --noEmit",e,t,n,r);return o.crashed||o.timedOut?null:o.exitCode===0}async function HAe(e,t,n){return new Promise(r=>{let o;try{o=n("git",["diff","--shortstat",`${t}..HEAD`],{cwd:e,stdio:["ignore","pipe","pipe"]})}catch{r(0);return}let i="";o.stdout?.on("data",s=>{i+=String(s)}),o.on("error",()=>r(0)),o.on("close",()=>{let s=/(\d+) insertions?\(\+\)/.exec(i),a=/(\d+) deletions?\(-\)/.exec(i),l=s?Number(s[1]):0,c=a?Number(a[1]):0;r(l-c)})})}function z8(e){let t=e.pass+e.fail;return t===0?0:e.pass/t}function J8(e){return e===!0?2:e===!1?1:0}function WAe(e,t){return e.length<=t?e:e.slice(0,t)+"\u2026"}function V8(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}async function Z8(e){try{return await jS.access(e),!0}catch{return!1}}Af();function e5(e,t){let n;try{n=t?._store??new yt}catch(r){return{skipped:!0,reason:r instanceof Error?r.message:String(r)}}try{let r=KAe(e);return{factId:n.storeFact({category:"learning",content:JSON.stringify(r),source_surface:"afk"})}}catch(r){return{skipped:!0,reason:r instanceof Error?r.message:String(r)}}}function KAe(e){let t=GAe(e.branches),n=e.winner??null,r=qAe(e,t);return{type:"farm-run",task:e.taskName,taskSlug:e.taskSlug,winner:n,why:r,scores:t,human_decision:e.human_decision??null,baseSha:e.baseSha,completedAt:e.completedAt}}function GAe(e){return e.map(t=>{let n=t.score??null;return{index:t.index,branch:t.branch,pass:n?.pass??0,fail:n?.fail??0,loc_delta:n?.loc_delta??0,lint_ok:n?.lint_ok??null,duration_ms:n?.duration_ms??0}})}function qAe(e,t){let{winner:n,branches:r}=e;if(n==null)return r.some(p=>p.score!=null)?`no winner: all ${r.length} branches failed tests`:"no winner: scoring data unavailable";let o=t.find(d=>d.index===n);if(!o)return`branch-${n} wins`;let i=o.pass>0?"\u2713":"\u2717",s=o.lint_ok===!0?"\u2713":o.lint_ok===!1?"\u2717":"?",a=o.loc_delta>=0?`+${o.loc_delta}`:String(o.loc_delta),c=t.filter(d=>d.index!==n).map(d=>d.loc_delta>=0?`+${d.loc_delta}`:String(d.loc_delta)),u=c.length>0?` (vs ${c.join(", ")} LoC)`:"";return`branch-${n} wins: tests${i}, lint${s}, ${a} LoC${u}`}var zAe="afk:f:";var JAe=/^[a-z0-9T][a-z0-9T-]{0,62}$/;function om(e,t){if(!JAe.test(t))throw new Error(`buildFarmCallback: invalid taskSlug ${JSON.stringify(t)}`);let n=`${zAe}${e}:${t}`,r=Buffer.byteLength(n,"utf8");if(r>64)throw new Error(`buildFarmCallback: payload ${r} bytes exceeds Telegram's 64-byte limit (slug=${t})`);return n}function t5(e){return{inline_keyboard:[[{text:"\u2705 Open PR",callback_data:om("p",e)},{text:"\u{1F501} Respawn from winner",callback_data:om("r",e)}],[{text:"\u{1F50D} Full diff",callback_data:om("d",e)},{text:"\u274C Discard all",callback_data:om("x",e)}]]}}function VAe(e){let{taskName:t,taskSlug:n,baseSha:r,branches:o,winner:i}=e,s=o.filter(b=>b.ok),a=o.filter(b=>!b.ok),l=o.length,c=s.length,u=s.map(b=>({index:b.index,score:b.score??null})),d=rm(u),p=new Map(o.map(b=>[b.index,b])),f=[];f.push(`\u{1F331} Farm complete: ${c}/${l} branches \u2014 ${t}`),f.push("");let g=1;for(let b of d){let w=p.get(b);if(!w)continue;let k=i!==void 0&&i===w.index,S=w.label?` (${w.label})`:"",E=w.score??null,x=E===null?"\u2014":E.pass>0?"\u2713":"\u2717",D=E===null?"\u2014":E.lint_ok===!0?"\u2713":E.lint_ok===!1?"\u2717":"?",I=E===null?"?":E.loc_delta>0?`+${E.loc_delta}`:E.loc_delta<0?`${E.loc_delta}`:"0",A=k?" \u2190 winner":"";f.push(`#${g} ${w.branch}${S} tests${x} lint${D} ${I} LoC${A}`),g++}let h=[...a].sort((b,w)=>b.index-w.index);for(let b of h){let w=b.label?` (${b.label})`:"",k=b.error??"unknown error";f.push(`#${g} ${b.branch}${w} failed: ${k}`),g++}f.push(""),i===void 0&&(f.push("\u26A0 no branch won (no successful + scored branches)"),f.push(""));let y=r.slice(0,7);return f.push(`base: ${y}`),f.push(`farm: ~/.afk/farms/${n}/`),f.join(`
2024
- `)}async function n5(e,t){let n=VAe(e),r=t5(e.taskSlug),o=t?._push??await Promise.resolve().then(()=>(qr(),kT)).then(i=>i.pushIfConfigured);try{let i=await o(n,{replyMarkup:r});return i===null?{sent:!1,reason:"telegram unconfigured"}:{sent:!0,chatCount:i.length}}catch(i){return{sent:!1,reason:i instanceof Error?i.message:String(i)}}}var r5=XAe(YAe);async function QAe(e,t){try{let{stdout:n}=await r5("git",["-C",e,"rev-list",`${t}..HEAD`,"--count"],{maxBuffer:4194304});return parseInt(n.trim(),10)||0}catch{return 0}}async function ZAe(e){try{let{stdout:t}=await r5("git",["-C",e,"status","--porcelain"],{maxBuffer:4194304});return t.trim()?t.trim().split(`
2023
+ `,"utf8"),o}function rm(e){let t=e.filter(r=>r.score!==null),n=e.filter(r=>r.score===null).map(r=>r.index).sort((r,o)=>r-o);return t.sort((r,o)=>{let i=r.score,s=o.score,a=z8(i),l=z8(s);if(a!==l)return l-a;let c=J8(i.lint_ok),u=J8(s.lint_ok);return c!==u?u-c:i.loc_delta!==s.loc_delta?i.loc_delta-s.loc_delta:r.index-o.index}),[...t.map(r=>r.index),...n]}async function BAe(e){try{let t=await jS.readFile(e,"utf8");return JSON.parse(t)}catch{return null}}async function UAe(e,t){let n=await t(nm(e,"package.json"));if(!V8(n))return;let r=n.scripts;return!V8(r)||typeof r.test!="string"?void 0:await Z8(nm(e,"pnpm-lock.yaml"))?"pnpm test":"npm test"}async function Q8(e,t,n,r,o){let i=o();return new Promise(s=>{let a;try{a=r(e,{cwd:t,shell:!0,stdio:["ignore","pipe","pipe"],env:{...process.env,CI:"1"}})}catch(p){s({exitCode:null,durationMs:o()-i,stderr:p instanceof Error?p.message:String(p),timedOut:!1,crashed:!0});return}let l="",c=!1,u=!1,d=setTimeout(()=>{c=!0,a.kill("SIGKILL")},n);a.stderr?.on("data",p=>{l+=String(p),l.length>64e3&&(l=l.slice(-32e3))}),a.on("error",p=>{u||(u=!0,clearTimeout(d),s({exitCode:null,durationMs:o()-i,stderr:p.message,timedOut:!1,crashed:!0}))}),a.on("close",p=>{u||(u=!0,clearTimeout(d),s({exitCode:p,durationMs:o()-i,stderr:l,timedOut:c,crashed:!1}))})})}async function jAe(e,t,n,r){if(!await Z8(nm(e,"tsconfig.json")))return null;let o=await Q8("npx --no-install tsc --noEmit",e,t,n,r);return o.crashed||o.timedOut?null:o.exitCode===0}async function HAe(e,t,n){return new Promise(r=>{let o;try{o=n("git",["diff","--shortstat",`${t}..HEAD`],{cwd:e,stdio:["ignore","pipe","pipe"]})}catch{r(0);return}let i="";o.stdout?.on("data",s=>{i+=String(s)}),o.on("error",()=>r(0)),o.on("close",()=>{let s=/(\d+) insertions?\(\+\)/.exec(i),a=/(\d+) deletions?\(-\)/.exec(i),l=s?Number(s[1]):0,c=a?Number(a[1]):0;r(l-c)})})}function z8(e){let t=e.pass+e.fail;return t===0?0:e.pass/t}function J8(e){return e===!0?2:e===!1?1:0}function WAe(e,t){return e.length<=t?e:e.slice(0,t)+"\u2026"}function V8(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}async function Z8(e){try{return await jS.access(e),!0}catch{return!1}}Af();function e6(e,t){let n;try{n=t?._store??new yt}catch(r){return{skipped:!0,reason:r instanceof Error?r.message:String(r)}}try{let r=KAe(e);return{factId:n.storeFact({category:"learning",content:JSON.stringify(r),source_surface:"afk"})}}catch(r){return{skipped:!0,reason:r instanceof Error?r.message:String(r)}}}function KAe(e){let t=GAe(e.branches),n=e.winner??null,r=qAe(e,t);return{type:"farm-run",task:e.taskName,taskSlug:e.taskSlug,winner:n,why:r,scores:t,human_decision:e.human_decision??null,baseSha:e.baseSha,completedAt:e.completedAt}}function GAe(e){return e.map(t=>{let n=t.score??null;return{index:t.index,branch:t.branch,pass:n?.pass??0,fail:n?.fail??0,loc_delta:n?.loc_delta??0,lint_ok:n?.lint_ok??null,duration_ms:n?.duration_ms??0}})}function qAe(e,t){let{winner:n,branches:r}=e;if(n==null)return r.some(p=>p.score!=null)?`no winner: all ${r.length} branches failed tests`:"no winner: scoring data unavailable";let o=t.find(d=>d.index===n);if(!o)return`branch-${n} wins`;let i=o.pass>0?"\u2713":"\u2717",s=o.lint_ok===!0?"\u2713":o.lint_ok===!1?"\u2717":"?",a=o.loc_delta>=0?`+${o.loc_delta}`:String(o.loc_delta),c=t.filter(d=>d.index!==n).map(d=>d.loc_delta>=0?`+${d.loc_delta}`:String(d.loc_delta)),u=c.length>0?` (vs ${c.join(", ")} LoC)`:"";return`branch-${n} wins: tests${i}, lint${s}, ${a} LoC${u}`}var zAe="afk:f:";var JAe=/^[a-z0-9T][a-z0-9T-]{0,62}$/;function om(e,t){if(!JAe.test(t))throw new Error(`buildFarmCallback: invalid taskSlug ${JSON.stringify(t)}`);let n=`${zAe}${e}:${t}`,r=Buffer.byteLength(n,"utf8");if(r>64)throw new Error(`buildFarmCallback: payload ${r} bytes exceeds Telegram's 64-byte limit (slug=${t})`);return n}function t6(e){return{inline_keyboard:[[{text:"\u2705 Open PR",callback_data:om("p",e)},{text:"\u{1F501} Respawn from winner",callback_data:om("r",e)}],[{text:"\u{1F50D} Full diff",callback_data:om("d",e)},{text:"\u274C Discard all",callback_data:om("x",e)}]]}}function VAe(e){let{taskName:t,taskSlug:n,baseSha:r,branches:o,winner:i}=e,s=o.filter(b=>b.ok),a=o.filter(b=>!b.ok),l=o.length,c=s.length,u=s.map(b=>({index:b.index,score:b.score??null})),d=rm(u),p=new Map(o.map(b=>[b.index,b])),f=[];f.push(`\u{1F331} Farm complete: ${c}/${l} branches \u2014 ${t}`),f.push("");let g=1;for(let b of d){let w=p.get(b);if(!w)continue;let k=i!==void 0&&i===w.index,S=w.label?` (${w.label})`:"",E=w.score??null,x=E===null?"\u2014":E.pass>0?"\u2713":"\u2717",D=E===null?"\u2014":E.lint_ok===!0?"\u2713":E.lint_ok===!1?"\u2717":"?",I=E===null?"?":E.loc_delta>0?`+${E.loc_delta}`:E.loc_delta<0?`${E.loc_delta}`:"0",A=k?" \u2190 winner":"";f.push(`#${g} ${w.branch}${S} tests${x} lint${D} ${I} LoC${A}`),g++}let h=[...a].sort((b,w)=>b.index-w.index);for(let b of h){let w=b.label?` (${b.label})`:"",k=b.error??"unknown error";f.push(`#${g} ${b.branch}${w} failed: ${k}`),g++}f.push(""),i===void 0&&(f.push("\u26A0 no branch won (no successful + scored branches)"),f.push(""));let y=r.slice(0,7);return f.push(`base: ${y}`),f.push(`farm: ~/.afk/farms/${n}/`),f.join(`
2024
+ `)}async function n6(e,t){let n=VAe(e),r=t6(e.taskSlug),o=t?._push??await Promise.resolve().then(()=>(qr(),kT)).then(i=>i.pushIfConfigured);try{let i=await o(n,{replyMarkup:r});return i===null?{sent:!1,reason:"telegram unconfigured"}:{sent:!0,chatCount:i.length}}catch(i){return{sent:!1,reason:i instanceof Error?i.message:String(i)}}}var r6=XAe(YAe);async function QAe(e,t){try{let{stdout:n}=await r6("git",["-C",e,"rev-list",`${t}..HEAD`,"--count"],{maxBuffer:4194304});return parseInt(n.trim(),10)||0}catch{return 0}}async function ZAe(e){try{let{stdout:t}=await r6("git",["-C",e,"status","--porcelain"],{maxBuffer:4194304});return t.trim()?t.trim().split(`
2025
2025
  `).filter(Boolean):[]}catch{return[]}}var G_=class extends Error{dirtyFiles;constructor(t){super(`Source repository has uncommitted changes after farm run. Dirty files:
2026
2026
  ${t.map(n=>` ${n}`).join(`
2027
- `)}`),this.name="FarmIsolationViolation",this.dirtyFiles=t}};function eCe(e,t){return e.length>=t?e:e+" ".repeat(t-e.length)}function tCe(e){if(e===void 0)return m.dim("\u2014");if(e===null)return m.dim("skipped");let t=e.fail===0&&e.pass>0?m.success("tests\u2713"):m.error("tests\u2717"),n=e.lint_ok===!0?m.success("lint\u2713"):e.lint_ok===!1?m.error("lint\u2717"):m.dim("lint?"),r=e.loc_delta>0?"+":"",o=m.dim(`${r}${e.loc_delta} LoC`);return`${t} ${n} ${o}`}function nCe(e,t,n,r){let o="\u2500".repeat(45);console.log(m.dim(o)),console.log(`farm: ${e}`),console.log(`slug: ${t}`),console.log("");let i=r.some(u=>u.score!=null),s=i?rm(r.map(u=>({index:u.index,score:u.score??null}))).map(u=>r.find(d=>d.index===u)):r;for(let u=0;u<s.length;u++){let d=s[u],p=n.find(w=>w.index===d.index),f=d.ok?m.success("\u2713"):m.error("\u2717"),g=eCe(p.branch,40),h=d.ok?m.dim(`(${d.commitCount} commit${d.commitCount===1?"":"s"})`):m.error(`[error: ${d.error}]`),y=i?m.brand(`#${u+1} `):"",b=i?` ${tCe(d.score)}`:"";console.log(`${y}branch-${d.index} ${f} ${g} ${h}${b}`),console.log(m.dim(` worktree: ${p.path}`))}console.log(m.dim(o));let a=r.filter(u=>u.ok).length,l=r.length;console.log(`${a}/${l} branches completed.`);let c=r.some(u=>u.score!=null&&u.score.pass>0);i&&!c&&console.log(m.warning("\u26A0 no branch passed tests \u2014 ranking falls back to lint + LoC"))}function rCe(e,t,n){let r=t.map(a=>{let l=e.branches.find(u=>u.index===a.index),c={index:a.index,branch:l?.branch??`(unknown-${a.index})`,ok:a.ok,commitCount:a.commitCount};return l?.label!==void 0&&(c.label=l.label),a.error!==void 0&&(c.error=a.error),a.score!==void 0&&(c.score=a.score),c}),o=rm(t.map(a=>({index:a.index,score:a.score??null}))),i;for(let a of o){let l=t.find(c=>c.index===a);if(!(!l||!l.ok||!l.score)&&l.score.pass>0&&l.score.fail===0){i=a;break}}if(i===void 0)for(let a of o){let l=t.find(c=>c.index===a);if(l?.ok&&l.score){i=a;break}}let s={taskName:e.taskName,taskSlug:e.taskSlug,baseSha:e.baseRef,startedAt:n,completedAt:new Date().toISOString(),branches:r};return i!==void 0&&(s.winner=i),e.human_decision!==void 0&&(s.human_decision=e.human_decision),s}async function oCe(e){let{task:t,branches:n,labels:r,model:o,baseRef:i,cwd:s=process.cwd(),failFast:a,taskSlug:l,score:c=!0,scoreTimeoutMs:u=HS,memoryWrite:d=!0,digest:p=!0,_createFarm:f=G8,_runSubagentDAG:g=Xy,_getCommitCount:h=QAe,_getSourceRepoDirtyFiles:y=ZAe,_scoreBranch:b=Y8,_writeScore:w=X8,_writeFarmFact:k=e5,_sendFarmDigest:S=n5,_setFarmMemoryFactId:E=q8,_createTraceWriter:x=ui}=e,D=new Date().toISOString();(!Number.isInteger(n)||n<1||n>16)&&(console.error(m.error(`--branches must be between 1 and 16 (got ${n})`)),process.exit(1)),r!==void 0&&r.length!==n&&(console.error(m.error(`--labels count (${r.length}) must equal --branches (${n})`)),process.exit(1));let I;try{I=await f({taskName:t,count:n,labels:r,cwd:s,baseRef:i,taskSlug:l})}catch(B){console.error(m.error(`Farm creation failed: ${B instanceof Error?B.message:String(B)}`)),process.exit(1)}let A=I.baseRef,C=o??tt(),P=Wt().prompt??"",N=I.branches.map(B=>({id:`branch-${B.index}`,agentType:`branch-${B.index}${B.label?` (${B.label})`:""}`,systemPrompt:P,promptBuilder:X=>(console.log(`[branch-${B.index}] started`),[`Task: ${t}`,"",`You are working in a dedicated git worktree. Your working directory has been set to: ${B.path}`,`Your branch is: ${B.branch}`,"","Complete the task. All file operations are restricted to this worktree by the runtime."].join(`
2027
+ `)}`),this.name="FarmIsolationViolation",this.dirtyFiles=t}};function eCe(e,t){return e.length>=t?e:e+" ".repeat(t-e.length)}function tCe(e){if(e===void 0)return m.dim("\u2014");if(e===null)return m.dim("skipped");let t=e.fail===0&&e.pass>0?m.success("tests\u2713"):m.error("tests\u2717"),n=e.lint_ok===!0?m.success("lint\u2713"):e.lint_ok===!1?m.error("lint\u2717"):m.dim("lint?"),r=e.loc_delta>0?"+":"",o=m.dim(`${r}${e.loc_delta} LoC`);return`${t} ${n} ${o}`}function nCe(e,t,n,r){let o="\u2500".repeat(45);console.log(m.dim(o)),console.log(`farm: ${e}`),console.log(`slug: ${t}`),console.log("");let i=r.some(u=>u.score!=null),s=i?rm(r.map(u=>({index:u.index,score:u.score??null}))).map(u=>r.find(d=>d.index===u)):r;for(let u=0;u<s.length;u++){let d=s[u],p=n.find(w=>w.index===d.index),f=d.ok?m.success("\u2713"):m.error("\u2717"),g=eCe(p.branch,40),h=d.ok?m.dim(`(${d.commitCount} commit${d.commitCount===1?"":"s"})`):m.error(`[error: ${d.error}]`),y=i?m.brand(`#${u+1} `):"",b=i?` ${tCe(d.score)}`:"";console.log(`${y}branch-${d.index} ${f} ${g} ${h}${b}`),console.log(m.dim(` worktree: ${p.path}`))}console.log(m.dim(o));let a=r.filter(u=>u.ok).length,l=r.length;console.log(`${a}/${l} branches completed.`);let c=r.some(u=>u.score!=null&&u.score.pass>0);i&&!c&&console.log(m.warning("\u26A0 no branch passed tests \u2014 ranking falls back to lint + LoC"))}function rCe(e,t,n){let r=t.map(a=>{let l=e.branches.find(u=>u.index===a.index),c={index:a.index,branch:l?.branch??`(unknown-${a.index})`,ok:a.ok,commitCount:a.commitCount};return l?.label!==void 0&&(c.label=l.label),a.error!==void 0&&(c.error=a.error),a.score!==void 0&&(c.score=a.score),c}),o=rm(t.map(a=>({index:a.index,score:a.score??null}))),i;for(let a of o){let l=t.find(c=>c.index===a);if(!(!l||!l.ok||!l.score)&&l.score.pass>0&&l.score.fail===0){i=a;break}}if(i===void 0)for(let a of o){let l=t.find(c=>c.index===a);if(l?.ok&&l.score){i=a;break}}let s={taskName:e.taskName,taskSlug:e.taskSlug,baseSha:e.baseRef,startedAt:n,completedAt:new Date().toISOString(),branches:r};return i!==void 0&&(s.winner=i),e.human_decision!==void 0&&(s.human_decision=e.human_decision),s}async function oCe(e){let{task:t,branches:n,labels:r,model:o,baseRef:i,cwd:s=process.cwd(),failFast:a,taskSlug:l,score:c=!0,scoreTimeoutMs:u=HS,memoryWrite:d=!0,digest:p=!0,_createFarm:f=G8,_runSubagentDAG:g=Xy,_getCommitCount:h=QAe,_getSourceRepoDirtyFiles:y=ZAe,_scoreBranch:b=Y8,_writeScore:w=X8,_writeFarmFact:k=e6,_sendFarmDigest:S=n6,_setFarmMemoryFactId:E=q8,_createTraceWriter:x=ui}=e,D=new Date().toISOString();(!Number.isInteger(n)||n<1||n>16)&&(console.error(m.error(`--branches must be between 1 and 16 (got ${n})`)),process.exit(1)),r!==void 0&&r.length!==n&&(console.error(m.error(`--labels count (${r.length}) must equal --branches (${n})`)),process.exit(1));let I;try{I=await f({taskName:t,count:n,labels:r,cwd:s,baseRef:i,taskSlug:l})}catch(B){console.error(m.error(`Farm creation failed: ${B instanceof Error?B.message:String(B)}`)),process.exit(1)}let A=I.baseRef,C=o??tt(),P=Wt().prompt??"",N=I.branches.map(B=>({id:`branch-${B.index}`,agentType:`branch-${B.index}${B.label?` (${B.label})`:""}`,systemPrompt:P,promptBuilder:X=>(console.log(`[branch-${B.index}] started`),[`Task: ${t}`,"",`You are working in a dedicated git worktree. Your working directory has been set to: ${B.path}`,`Your branch is: ${B.branch}`,"","Complete the task. All file operations are restricted to this worktree by the runtime."].join(`
2028
2028
  `)),model:C,idPrefix:`farm-${I.taskSlug}-branch-${B.index}`,cwd:B.path,readRoots:[B.path],writeRoots:[B.path]})),q=x(),O=new AbortController,H=new Se({parentAbortSignal:O.signal,...q!==null?{traceWriter:q.writer}:{},surface:"cli"}),K={sessionId:`farm-${I.taskSlug}`,abortSignal:O.signal,surface:"cli"},_;try{_=await g({manager:H,parentSession:K,nodes:N,edges:[],failFast:a})}catch(B){throw console.error(m.error(`Farm dispatch failed: ${B instanceof Error?B.message:String(B)}`)),B}finally{O.abort()}let F=[];for(let B of I.branches){let X=_.failed.find(se=>se.id===`branch-${B.index}`),j=_.skipped.includes(`branch-${B.index}`);if(X||j){let se=X?X.error.message:"skipped";console.log(`[branch-${B.index}] \u2717 failed: ${se}`),F.push({index:B.index,ok:!1,commitCount:0,error:se});continue}let ee=await h(B.path,A);if(ee===0){let se="no commits made";console.log(`[branch-${B.index}] \u2717 failed: ${se}`),F.push({index:B.index,ok:!1,commitCount:0,error:se})}else console.log(`[branch-${B.index}] \u2713 done`),F.push({index:B.index,ok:!0,commitCount:ee})}let M=await y(s);if(c)for(let B of F){if(!B.ok){B.score=null;continue}let X=I.branches.find(ee=>ee.index===B.index);console.log(`[branch-${B.index}] scoring\u2026`);let j=await b({branchPath:X.path,baseSha:A,timeoutMs:u});B.score=j;try{await w(I.farmDir,B.index,j)}catch(ee){console.error(m.warning(`[branch-${B.index}] score.json write failed: ${ee instanceof Error?ee.message:String(ee)}`))}}if(nCe(t,I.taskSlug,I.branches,F),d||p){let B=rCe(I,F,D);if(d){let X=k(B);if("skipped"in X)console.error(m.warning(`[memory] write skipped: ${X.reason}`));else{let{factId:j}=X;try{await E(I.taskSlug,j)}catch(ee){console.error(m.warning(`[memory] setFarmMemoryFactId failed: ${ee.message}`))}}}if(p){let X=await S(B);X.sent?console.log(m.dim(`[telegram] digest sent (${X.chatCount} chat${X.chatCount===1?"":"s"})`)):X.reason&&X.reason!=="telegram unconfigured"&&console.error(m.warning(`[telegram] digest failed: ${X.reason}`))}}if(M.length>0){let B=new G_(M);console.error(m.error(`
2029
- \u26A0 ISOLATION VIOLATION`)),console.error(m.error(B.message)),process.exit(1)}let $=F.every(B=>B.ok);process.exit($?0:1)}function o5(e){e.command("farm").description("Run a task across N speculative git worktree branches in parallel").argument("<task>","Task description to run on each branch").option("-n, --branches <number>","Number of branches to spawn (1-16)","3").option("--labels <labels>","Comma-separated branch labels (count must equal --branches)").option("-m, --model <model>","Model to use",tt()).option("--base-ref <ref>","Base git ref (default: HEAD)").option("--cwd <path>","Source repo root (default: process.cwd())").option("--fail-fast","Abort remaining branches on first failure",!1).option("--task-slug <slug>","Deterministic task slug override (for tests)").option("--no-score","Skip the post-run scorer (tests + lint + LoC)").option("--score-timeout <ms>",`Per-branch test timeout in ms (default ${HS})`).option("--no-memory","Skip writing the farm-run fact to cross-session memory").option("--no-digest","Skip pushing the Telegram digest on completion").action(async(t,n)=>{let r=parseInt(n.branches,10),o=n.labels?n.labels.split(",").map(s=>s.trim()).filter(Boolean):void 0,i=n.scoreTimeout?parseInt(n.scoreTimeout,10):void 0;i!==void 0&&(!Number.isFinite(i)||i<1)&&(console.error(m.error(`--score-timeout must be a positive integer (got "${n.scoreTimeout}")`)),process.exit(1));try{await oCe({task:t,branches:r,labels:o,model:n.model,baseRef:n.baseRef,cwd:n.cwd,failFast:n.failFast,taskSlug:n.taskSlug,score:n.score,memoryWrite:n.memory,digest:n.digest,...i!==void 0?{scoreTimeoutMs:i}:{}})}catch(s){console.error(s),process.exitCode=1}})}W();import{execFile as iCe}from"node:child_process";el();wt();import{promisify as sCe}from"node:util";var q_=sCe(iCe);async function i5(){try{return(await q_("git",["rev-parse","--show-toplevel"])).stdout.trim()}catch{throw new Error("Not in a git repository.")}}function aCe(e){return["empty","orphaned-dir","orphaned-registration","dead-owner"].includes(e)?m.error("yes"):e==="stale-dirty"||e==="stale-clean"?m.warning("warn"):m.success("no")}var s5=["interactive","diagnose","all"];function lCe(e){if(s5.includes(e))return e;throw new Error(`Invalid --scope value: '${e}'. Allowed: ${s5.join(" | ")}.`)}function cCe(e){if(e<=0)return"-";let t=e/864e5;return t<1?`${Math.max(1,Math.round(e/36e5))}h`:`${Math.round(t)}d`}function a5(e){let t=e.command("worktree").description("Manage git worktrees created by afk");t.command("list").description("List all afk-managed worktrees and show prune candidates (dry-run only)").action(async()=>{let n;try{n=await i5()}catch(i){J(i)}let r;try{r=await vn({execFile:q_,repoRoot:n,dryRun:!0})}catch(i){J(new Error(`Sweep failed: ${i.message}`))}let o=["PATH".padEnd(45),"OWNER".padEnd(12),"AGE".padEnd(6),"STATUS".padEnd(22),"PRUNE?"].join(" | ");console.log(m.heading(o)),console.log("-".repeat(o.length));for(let i of r.candidates){let s=[i.path.slice(-44).padEnd(45),i.owner.padEnd(12),cCe(i.ageMs).padEnd(6),i.verdict.padEnd(22),aCe(i.verdict)].join(" | ");console.log(s)}if(r.candidates.length===0&&console.log(m.dim(" (no afk-managed worktrees found)")),r.warnings.length>0){console.log("");for(let i of r.warnings)console.log(m.warning(i))}}),t.command("prune").description("Remove stale, empty, and orphaned worktrees").option("--apply","Execute removals (default is dry-run)",!1).option("--max-age-days-clean <n>","Max age (days) for clean worktrees before removal").option("--max-age-days-dirty <n>","Max age (days) for dirty worktrees before warning").option("--scope <scope>","Scope: interactive | diagnose | all","all").action(async n=>{let r;try{r=await i5()}catch(w){J(w)}let i=ze().daemon?.worktreePrune,s=parseInt(T.AFK_WORKTREE_MAX_AGE_CLEAN??"",10),a=parseInt(T.AFK_WORKTREE_MAX_AGE_DIRTY??"",10),l=n.maxAgeDaysClean!==void 0?parseInt(n.maxAgeDaysClean,10):i?.maxAgeDaysClean??(Number.isNaN(s)?14:s),c=n.maxAgeDaysDirty!==void 0?parseInt(n.maxAgeDaysDirty,10):i?.maxAgeDaysDirty??(Number.isNaN(a)?30:a),u;try{u=lCe(n.scope)}catch(w){J(w)}let d={execFile:q_,repoRoot:r,dryRun:!n.apply,maxAgeDaysClean:l,maxAgeDaysDirty:c,scope:u,...n.apply===!0?{bypassSoftLaunch:!0}:{}},p;try{p=await vn(d)}catch(w){J(new Error(`Sweep failed: ${w.message}`))}p.dryRun&&console.log(m.warning("\u{1F50D} Dry-run mode \u2014 no changes made."));let f={};for(let w of p.candidates)f[w.verdict]=(f[w.verdict]??0)+1;let g=p.warnings.filter(w=>w.startsWith("[WARN]")).length,h=p.warnings.filter(w=>w.startsWith("[ERROR]")).length,y=Object.entries(f).sort(([w],[k])=>w.localeCompare(k)).map(([w,k])=>`${w}=${k}`);console.log(`Removed: ${p.removed.length}, Warned: ${g}, Errors: ${h}`+(y.length>0?` [${y.join(" ")}]`:""));for(let w of p.candidates){let S=p.removed.includes(w.path)?m.error("\u2717"):m.success("\u2713");console.log(` ${S} [${w.verdict.padEnd(22)}] ${w.path}`)}if(p.warnings.length>0){console.log("");for(let w of p.warnings)w.startsWith("[ERROR]")?console.error(m.error(w)):console.log(m.warning(w))}p.warnings.some(w=>w.startsWith("[ERROR]"))&&process.exit(1)})}import{spawn as uCe}from"child_process";var dCe=/^\d+\.\d+\.\d+(-[\da-z.]+)?$/i;function pCe(e,t){let n=e.split(".").map(Number),r=t.split(".").map(Number),o=Math.max(n.length,r.length);for(let i=0;i<o;i++){let s=n[i]??0,a=r[i]??0;if(a>s)return!0;if(a<s)return!1}return!1}function l5(e){e.command("update").alias("upgrade").description("Update agent-afk to the latest published version").option("--check","Only check whether an update is available; do not install").option("--pin <version>","Install a specific version instead of latest (must be valid semver)").action(async t=>{let n=Pr();if(t.check===!0){process.stderr.write(`Checking for updates\u2026
2029
+ \u26A0 ISOLATION VIOLATION`)),console.error(m.error(B.message)),process.exit(1)}let $=F.every(B=>B.ok);process.exit($?0:1)}function o6(e){e.command("farm").description("Run a task across N speculative git worktree branches in parallel").argument("<task>","Task description to run on each branch").option("-n, --branches <number>","Number of branches to spawn (1-16)","3").option("--labels <labels>","Comma-separated branch labels (count must equal --branches)").option("-m, --model <model>","Model to use",tt()).option("--base-ref <ref>","Base git ref (default: HEAD)").option("--cwd <path>","Source repo root (default: process.cwd())").option("--fail-fast","Abort remaining branches on first failure",!1).option("--task-slug <slug>","Deterministic task slug override (for tests)").option("--no-score","Skip the post-run scorer (tests + lint + LoC)").option("--score-timeout <ms>",`Per-branch test timeout in ms (default ${HS})`).option("--no-memory","Skip writing the farm-run fact to cross-session memory").option("--no-digest","Skip pushing the Telegram digest on completion").action(async(t,n)=>{let r=parseInt(n.branches,10),o=n.labels?n.labels.split(",").map(s=>s.trim()).filter(Boolean):void 0,i=n.scoreTimeout?parseInt(n.scoreTimeout,10):void 0;i!==void 0&&(!Number.isFinite(i)||i<1)&&(console.error(m.error(`--score-timeout must be a positive integer (got "${n.scoreTimeout}")`)),process.exit(1));try{await oCe({task:t,branches:r,labels:o,model:n.model,baseRef:n.baseRef,cwd:n.cwd,failFast:n.failFast,taskSlug:n.taskSlug,score:n.score,memoryWrite:n.memory,digest:n.digest,...i!==void 0?{scoreTimeoutMs:i}:{}})}catch(s){console.error(s),process.exitCode=1}})}W();import{execFile as iCe}from"node:child_process";el();wt();import{promisify as sCe}from"node:util";var q_=sCe(iCe);async function i6(){try{return(await q_("git",["rev-parse","--show-toplevel"])).stdout.trim()}catch{throw new Error("Not in a git repository.")}}function aCe(e){return["empty","orphaned-dir","orphaned-registration","dead-owner"].includes(e)?m.error("yes"):e==="stale-dirty"||e==="stale-clean"?m.warning("warn"):m.success("no")}var s6=["interactive","diagnose","all"];function lCe(e){if(s6.includes(e))return e;throw new Error(`Invalid --scope value: '${e}'. Allowed: ${s6.join(" | ")}.`)}function cCe(e){if(e<=0)return"-";let t=e/864e5;return t<1?`${Math.max(1,Math.round(e/36e5))}h`:`${Math.round(t)}d`}function a6(e){let t=e.command("worktree").description("Manage git worktrees created by afk");t.command("list").description("List all afk-managed worktrees and show prune candidates (dry-run only)").action(async()=>{let n;try{n=await i6()}catch(i){J(i)}let r;try{r=await vn({execFile:q_,repoRoot:n,dryRun:!0})}catch(i){J(new Error(`Sweep failed: ${i.message}`))}let o=["PATH".padEnd(45),"OWNER".padEnd(12),"AGE".padEnd(6),"STATUS".padEnd(22),"PRUNE?"].join(" | ");console.log(m.heading(o)),console.log("-".repeat(o.length));for(let i of r.candidates){let s=[i.path.slice(-44).padEnd(45),i.owner.padEnd(12),cCe(i.ageMs).padEnd(6),i.verdict.padEnd(22),aCe(i.verdict)].join(" | ");console.log(s)}if(r.candidates.length===0&&console.log(m.dim(" (no afk-managed worktrees found)")),r.warnings.length>0){console.log("");for(let i of r.warnings)console.log(m.warning(i))}}),t.command("prune").description("Remove stale, empty, and orphaned worktrees").option("--apply","Execute removals (default is dry-run)",!1).option("--max-age-days-clean <n>","Max age (days) for clean worktrees before removal").option("--max-age-days-dirty <n>","Max age (days) for dirty worktrees before warning").option("--scope <scope>","Scope: interactive | diagnose | all","all").action(async n=>{let r;try{r=await i6()}catch(w){J(w)}let i=ze().daemon?.worktreePrune,s=parseInt(T.AFK_WORKTREE_MAX_AGE_CLEAN??"",10),a=parseInt(T.AFK_WORKTREE_MAX_AGE_DIRTY??"",10),l=n.maxAgeDaysClean!==void 0?parseInt(n.maxAgeDaysClean,10):i?.maxAgeDaysClean??(Number.isNaN(s)?14:s),c=n.maxAgeDaysDirty!==void 0?parseInt(n.maxAgeDaysDirty,10):i?.maxAgeDaysDirty??(Number.isNaN(a)?30:a),u;try{u=lCe(n.scope)}catch(w){J(w)}let d={execFile:q_,repoRoot:r,dryRun:!n.apply,maxAgeDaysClean:l,maxAgeDaysDirty:c,scope:u,...n.apply===!0?{bypassSoftLaunch:!0}:{}},p;try{p=await vn(d)}catch(w){J(new Error(`Sweep failed: ${w.message}`))}p.dryRun&&console.log(m.warning("\u{1F50D} Dry-run mode \u2014 no changes made."));let f={};for(let w of p.candidates)f[w.verdict]=(f[w.verdict]??0)+1;let g=p.warnings.filter(w=>w.startsWith("[WARN]")).length,h=p.warnings.filter(w=>w.startsWith("[ERROR]")).length,y=Object.entries(f).sort(([w],[k])=>w.localeCompare(k)).map(([w,k])=>`${w}=${k}`);console.log(`Removed: ${p.removed.length}, Warned: ${g}, Errors: ${h}`+(y.length>0?` [${y.join(" ")}]`:""));for(let w of p.candidates){let S=p.removed.includes(w.path)?m.error("\u2717"):m.success("\u2713");console.log(` ${S} [${w.verdict.padEnd(22)}] ${w.path}`)}if(p.warnings.length>0){console.log("");for(let w of p.warnings)w.startsWith("[ERROR]")?console.error(m.error(w)):console.log(m.warning(w))}p.warnings.some(w=>w.startsWith("[ERROR]"))&&process.exit(1)})}import{spawn as uCe}from"child_process";var dCe=/^\d+\.\d+\.\d+(-[\da-z.]+)?$/i;function pCe(e,t){let n=e.split(".").map(Number),r=t.split(".").map(Number),o=Math.max(n.length,r.length);for(let i=0;i<o;i++){let s=n[i]??0,a=r[i]??0;if(a>s)return!0;if(a<s)return!1}return!1}function l6(e){e.command("update").alias("upgrade").description("Update agent-afk to the latest published version").option("--check","Only check whether an update is available; do not install").option("--pin <version>","Install a specific version instead of latest (must be valid semver)").action(async t=>{let n=Pr();if(t.check===!0){process.stderr.write(`Checking for updates\u2026
2030
2030
  `);let s=await xS();if(s===void 0){console.log(m.warning("Could not reach the npm registry to check for updates.")),console.log(m.dim(` Current: ${n}`)),process.exitCode=1;return}if(RS(s),pCe(n,s)){console.log(`${m.bold("Update available:")} ${m.dim(n)} \u2192 ${m.bold(s)}`),console.log(m.dim(" Run `afk update` to install."));return}console.log(`agent-afk ${m.bold(n)} is up to date.`);return}if(t.pin!==void 0&&!dCe.test(t.pin)){console.error(m.warning(`Invalid version: ${JSON.stringify(t.pin)}. Must be valid semver (e.g. 1.2.3 or 1.2.3-beta.1).`)),process.exitCode=1;return}let r=t.pin;if(r===void 0){if(process.stderr.write(`Fetching latest version\u2026
2031
- `),r=await xS(),r===void 0){console.error(m.warning("Could not reach the npm registry. Aborting.")),process.exitCode=1;return}if(RS(r),r===n){console.log(`agent-afk ${m.bold(n)} is up to date.`);return}}console.log(`Updating agent-afk: ${m.dim(n)} \u2192 ${m.bold(r)}`),console.log(m.dim(` npm install -g agent-afk@${r}`));let{code:o,signal:i}=await mCe(r);o===0?(b_(r),console.log(m.success(`\u2713 agent-afk@${r} installed.`))):i!==null?(console.error(m.warning(`npm install was killed by signal ${i}.`)),process.exitCode=1):(console.error(m.warning(`npm install exited with code ${o??1}.`)),process.exitCode=o??1)})}function mCe(e){return new Promise(t=>{let n=uCe("npm",["install","-g",`agent-afk@${e}`],{stdio:"inherit"});n.on("error",()=>t({code:1,signal:null})),n.on("exit",(r,o)=>t({code:r,signal:o}))})}import{existsSync as fCe,readFileSync as gCe}from"node:fs";kg();G();LT();function c5(e){let t=e.command("schedule").description("Manage scheduled daemon tasks");t.command("add").description("Add a new scheduled task").requiredOption("--name <name>","Human-readable label").requiredOption("--command <cmd>","Command to run").requiredOption("--cron <expr>","Cron expression (5-field)").option("--trigger <mode>","cron | sessionstart | both","cron").option("--notify <when>","failure | always | never","failure").option("--disabled","Add in disabled state",!1).action(async n=>{try{let r=Sg({name:n.name,command:n.command,cron:n.cron,trigger:n.trigger,notifyOn:n.notify,enabled:!n.disabled});(r.enabled?await Un("POST","/tasks",{taskId:r.id,command:r.command,cron:r.cron,trigger:r.trigger,notifyOn:r.notifyOn}):await Un("DELETE",`/tasks/${r.id}`)).synced||console.error(`\u26A0\uFE0F ${Lo}`),console.log(`\u2705 Added: ${r.id} \u2014 ${r.name}`)}catch(r){J(r)}}),t.command("list").description("List all scheduled tasks").action(()=>{try{let n=wn();if(n.length===0){console.log("No scheduled tasks.");return}let r="ID | NAME | CRON | ENABLED",o="-".repeat(r.length);console.log(r),console.log(o);for(let i of n)console.log([i.id.padEnd(20),i.name.padEnd(30),i.cron.padEnd(15),String(i.enabled)].join(" | "))}catch(n){J(n)}}),t.command("remove <id>").description("Permanently remove a scheduled task").action(async n=>{try{vg(n)||(console.error(`Task not found: ${n}`),process.exit(1)),(await Un("DELETE",`/tasks/${n}`)).synced||console.error(`\u26A0\uFE0F ${Lo}`),console.log(`\u2705 Removed: ${n}`)}catch(r){J(r)}}),t.command("enable <id>").description("Enable a scheduled task").action(async n=>{try{let r=nd(n);r||(console.error(`Task not found: ${n}`),process.exit(1));let o=wn();cs(o.map(s=>s.id===n?{...s,enabled:!0,updatedAt:new Date().toISOString()}:s)),(await Un("POST","/tasks",{taskId:r.id,command:r.command,cron:r.cron,trigger:r.trigger,notifyOn:r.notifyOn})).synced||console.error(`\u26A0\uFE0F ${Lo}`),console.log(`\u2705 Enabled: ${n}`)}catch(r){J(r)}}),t.command("disable <id>").description("Disable a scheduled task").action(async n=>{try{nd(n)||(console.error(`Task not found: ${n}`),process.exit(1));let o=wn();cs(o.map(s=>s.id===n?{...s,enabled:!1,updatedAt:new Date().toISOString()}:s)),(await Un("DELETE",`/tasks/${n}`)).synced||console.error(`\u26A0\uFE0F ${Lo}`),console.log(`\u2705 Disabled: ${n}`)}catch(r){J(r)}}),t.command("logs <id>").description("Show recent execution history for a task").option("-n, --limit <n>","Number of records to show","10").action((n,r)=>{try{let o=Math.min(Math.max(1,parseInt(r.limit,10)||10),50),i=tr();if(!fCe(i)){console.log(`No telemetry found for task: ${n}`);return}let s=gCe(i),c=(s.length>1048576?s.subarray(s.length-1048576):s).toString("utf-8").split(`
2032
- `),u=[];for(let p=c.length-1;p>=0;p-=1){let f=c[p];if(f)try{let g=JSON.parse(f);if(g.taskId!==n)continue;if(u.push(g),u.length>=o)break}catch{continue}}let d=u.reverse();if(d.length===0){console.log(`No history found for task: ${n}`);return}console.log(JSON.stringify(d,null,2))}catch(o){J(o)}})}ay();function u5(e){return new Date(e).toISOString().replace("T"," ").slice(0,19)}function Dc(e,t){return e.length>=t?e:e+" ".repeat(t-e.length)}var d5=9,WS=50,p5=22;function hCe(e){let t=Dc(e.jobId,p5),n=Dc(e.status,d5),r=e.label.length>WS?`${e.label.slice(0,WS-1)}\u2026`:Dc(e.label,WS),o=u5(e.startedAt),i=e.endedAt!==void 0?u5(e.endedAt):"\u2014";return`${t} ${n} ${r} ${o} ${i}`}function yCe(e){return e.type==="done"||e.type==="error"}function m5(e){let t=e.command("bg").description(`Inspect persisted background subagent job logs.
2031
+ `),r=await xS(),r===void 0){console.error(m.warning("Could not reach the npm registry. Aborting.")),process.exitCode=1;return}if(RS(r),r===n){console.log(`agent-afk ${m.bold(n)} is up to date.`);return}}console.log(`Updating agent-afk: ${m.dim(n)} \u2192 ${m.bold(r)}`),console.log(m.dim(` npm install -g agent-afk@${r}`));let{code:o,signal:i}=await mCe(r);o===0?(b_(r),console.log(m.success(`\u2713 agent-afk@${r} installed.`))):i!==null?(console.error(m.warning(`npm install was killed by signal ${i}.`)),process.exitCode=1):(console.error(m.warning(`npm install exited with code ${o??1}.`)),process.exitCode=o??1)})}function mCe(e){return new Promise(t=>{let n=uCe("npm",["install","-g",`agent-afk@${e}`],{stdio:"inherit"});n.on("error",()=>t({code:1,signal:null})),n.on("exit",(r,o)=>t({code:r,signal:o}))})}import{existsSync as fCe,readFileSync as gCe}from"node:fs";kg();G();LT();function c6(e){let t=e.command("schedule").description("Manage scheduled daemon tasks");t.command("add").description("Add a new scheduled task").requiredOption("--name <name>","Human-readable label").requiredOption("--command <cmd>","Command to run").requiredOption("--cron <expr>","Cron expression (5-field)").option("--trigger <mode>","cron | sessionstart | both","cron").option("--notify <when>","failure | always | never","failure").option("--disabled","Add in disabled state",!1).action(async n=>{try{let r=Sg({name:n.name,command:n.command,cron:n.cron,trigger:n.trigger,notifyOn:n.notify,enabled:!n.disabled});(r.enabled?await Un("POST","/tasks",{taskId:r.id,command:r.command,cron:r.cron,trigger:r.trigger,notifyOn:r.notifyOn}):await Un("DELETE",`/tasks/${r.id}`)).synced||console.error(`\u26A0\uFE0F ${Lo}`),console.log(`\u2705 Added: ${r.id} \u2014 ${r.name}`)}catch(r){J(r)}}),t.command("list").description("List all scheduled tasks").action(()=>{try{let n=wn();if(n.length===0){console.log("No scheduled tasks.");return}let r="ID | NAME | CRON | ENABLED",o="-".repeat(r.length);console.log(r),console.log(o);for(let i of n)console.log([i.id.padEnd(20),i.name.padEnd(30),i.cron.padEnd(15),String(i.enabled)].join(" | "))}catch(n){J(n)}}),t.command("remove <id>").description("Permanently remove a scheduled task").action(async n=>{try{vg(n)||(console.error(`Task not found: ${n}`),process.exit(1)),(await Un("DELETE",`/tasks/${n}`)).synced||console.error(`\u26A0\uFE0F ${Lo}`),console.log(`\u2705 Removed: ${n}`)}catch(r){J(r)}}),t.command("enable <id>").description("Enable a scheduled task").action(async n=>{try{let r=nd(n);r||(console.error(`Task not found: ${n}`),process.exit(1));let o=wn();cs(o.map(s=>s.id===n?{...s,enabled:!0,updatedAt:new Date().toISOString()}:s)),(await Un("POST","/tasks",{taskId:r.id,command:r.command,cron:r.cron,trigger:r.trigger,notifyOn:r.notifyOn})).synced||console.error(`\u26A0\uFE0F ${Lo}`),console.log(`\u2705 Enabled: ${n}`)}catch(r){J(r)}}),t.command("disable <id>").description("Disable a scheduled task").action(async n=>{try{nd(n)||(console.error(`Task not found: ${n}`),process.exit(1));let o=wn();cs(o.map(s=>s.id===n?{...s,enabled:!1,updatedAt:new Date().toISOString()}:s)),(await Un("DELETE",`/tasks/${n}`)).synced||console.error(`\u26A0\uFE0F ${Lo}`),console.log(`\u2705 Disabled: ${n}`)}catch(r){J(r)}}),t.command("logs <id>").description("Show recent execution history for a task").option("-n, --limit <n>","Number of records to show","10").action((n,r)=>{try{let o=Math.min(Math.max(1,parseInt(r.limit,10)||10),50),i=tr();if(!fCe(i)){console.log(`No telemetry found for task: ${n}`);return}let s=gCe(i),c=(s.length>1048576?s.subarray(s.length-1048576):s).toString("utf-8").split(`
2032
+ `),u=[];for(let p=c.length-1;p>=0;p-=1){let f=c[p];if(f)try{let g=JSON.parse(f);if(g.taskId!==n)continue;if(u.push(g),u.length>=o)break}catch{continue}}let d=u.reverse();if(d.length===0){console.log(`No history found for task: ${n}`);return}console.log(JSON.stringify(d,null,2))}catch(o){J(o)}})}ay();function u6(e){return new Date(e).toISOString().replace("T"," ").slice(0,19)}function Dc(e,t){return e.length>=t?e:e+" ".repeat(t-e.length)}var d6=9,WS=50,p6=22;function hCe(e){let t=Dc(e.jobId,p6),n=Dc(e.status,d6),r=e.label.length>WS?`${e.label.slice(0,WS-1)}\u2026`:Dc(e.label,WS),o=u6(e.startedAt),i=e.endedAt!==void 0?u6(e.endedAt):"\u2014";return`${t} ${n} ${r} ${o} ${i}`}function yCe(e){return e.type==="done"||e.type==="error"}function m6(e){let t=e.command("bg").description(`Inspect persisted background subagent job logs.
2033
2033
  Note: bg jobs are tied to the parent REPL process \u2014 if the REPL exits,
2034
2034
  the job dies. This command reads the persisted log.`);t.command("list").description("List background jobs from disk (most recent first)").option("-n, --max <number>","Maximum jobs to show","20").action(async n=>{try{let r=Math.min(100,Math.max(1,parseInt(n.max,10)||20)),i=(await Tr.listJobs()).slice(0,r);if(i.length===0){process.stdout.write(`No background job logs found in ~/.afk/state/bg/
2035
- `);return}let s=Dc("JOB ID",p5)+" "+Dc("STATUS",d5)+" "+Dc("LABEL",WS)+" STARTED AT ENDED AT";process.stdout.write(s+`
2035
+ `);return}let s=Dc("JOB ID",p6)+" "+Dc("STATUS",d6)+" "+Dc("LABEL",WS)+" STARTED AT ENDED AT";process.stdout.write(s+`
2036
2036
  `),process.stdout.write("-".repeat(s.length)+`
2037
2037
  `);for(let a of i)process.stdout.write(hCe(a)+`
2038
2038
  `)}catch(r){J(r)}}),t.command("tail <jobId>").description(`Stream events from a background job log.
@@ -2042,51 +2042,51 @@ the job dies. This command reads the persisted log.`).option("--from-start","Rep
2042
2042
  `),yCe(i))break}catch(o){J(o)}}),t.command("replay <jobId>").description(`Replay all persisted events for a background job (alias for tail --from-start --no-follow).
2043
2043
  Note: bg jobs are tied to the parent REPL process \u2014 if the REPL exits,
2044
2044
  the job dies. This command reads the persisted log.`).action(async n=>{try{for await(let r of Tr.readEvents(n))process.stdout.write(JSON.stringify(r)+`
2045
- `)}catch(r){J(r)}})}import{readFile as h5,readdir as bCe,stat as wCe}from"node:fs/promises";import{join as KS}from"node:path";G();Ul();function J_(){return KS(fe(),"witness")}async function y5(){let e=J_(),t;try{t=await bCe(e)}catch(r){if(r.code==="ENOENT")return[];throw r}let n=[];for(let r of t){let o=KS(e,r,"trace.jsonl");try{let i=await wCe(o);i.isFile()&&n.push({sessionId:r,tracePath:o,mtimeMs:i.mtimeMs,exists:!0})}catch{}}return n.sort((r,o)=>o.mtimeMs-r.mtimeMs),n}async function SCe(){return(await y5())[0]?.sessionId??null}function vCe(e){if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.kind=="string"&&typeof t.seq=="number"&&typeof t.payload=="object"&&t.payload!==null}function kCe(e){let t=[],n=0;for(let r of e.split(`
2046
- `))if(r.trim()!=="")try{let o=JSON.parse(r);vCe(o)?t.push(o):n++}catch{n++}return{events:t,malformed:n}}async function f5(e){let t=e;if(e==="latest"){let o=await SCe();if(o===null)throw new Error(`No traces found under ${J_()}. Run an agent session first, or pass an explicit session id (see \`afk trace list\`).`);t=o}let n=KS(nr(t),"trace.jsonl"),r=await g5(n);if(r===null){let o=await TCe(t);if(o.kind==="disabled")throw new Error(`Session "${t}" ran with tracing disabled \u2014 its ledger records traceLabel: null, so no witness trace was written (tracing is off when AFK_TRACE_DISABLED=1).`);if(o.kind==="label"&&o.label!==t)try{let i=KS(nr(o.label),"trace.jsonl"),s=await g5(i);s!==null&&(n=i,r=s)}catch{}}if(r===null)throw new Error(`No trace found for session "${t}" at ${n}. See \`afk trace list\` for available sessions.`);return{sessionId:t,tracePath:n,...kCe(r)}}async function g5(e){try{return await h5(e,"utf8")}catch(t){if(t.code==="ENOENT")return null;throw t}}async function TCe(e){try{for await(let t of Bl(e))if(t.kind==="meta")return typeof t.traceLabel=="string"&&t.traceLabel.length>0?{kind:"label",label:t.traceLabel}:t.traceLabel===null?{kind:"disabled"}:{kind:"none"}}catch{}return{kind:"none"}}function wo(e){if(e<1e3)return`${e}ms`;if(e<6e4)return`${(e/1e3).toFixed(1)}s`;let t=Math.floor(e/6e4),n=Math.round(e%6e4/1e3);return`${t}m${n}s`}function z_(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function Fc(e){return`$${e.toFixed(4)}`}function ECe(e){return e.length>=19?e.slice(11,19):e}function xi(e,t){return e.length>t?`${e.slice(0,t-1)}\u2026`:e}function RCe(e){return e.length>=9?e:e+" ".repeat(9-e.length)}function xCe(e,t){let n=ECe(e.ts),r=(o,i)=>` ${n} ${RCe(o)} ${i}`;switch(e.kind){case"tool_call":{let o=e.payload;if(o.phase==="started"){let l=!t.completedToolIds.has(o.toolUseId);if(!t.showAll&&!l)return null;let c=o.subagentId?` [${o.subagentId}]`:"",u=l?"started (no completion recorded)":"started";return r("tool",`${o.name} ${u}${c}`)}let i=o.isError?"ERR":"ok",s=o.truncated?" (truncated)":"",a=o.subagentId?` [${o.subagentId}]`:"";return r("tool",`${o.name} ${i} ${wo(o.durationMs)} ${z_(o.resultBytes)}${s}${a}`)}case"hook_decision":{let o=e.payload;if(o.decision===void 0)return null;if(o.decision==="block"){let s=o.blockedTool?` ${o.blockedTool}`:"",a=o.reason?` (${xi(o.reason,80)})`:"";return r("hook",`BLOCK ${o.hookEvent}${s}${a}`)}let i=o.reason?` (${xi(o.reason,80)})`:"";return r("hook",`approve ${o.hookEvent}${i}`)}case"subagent_lifecycle":{let o=e.payload;switch(o.transition){case"started":{let i=o.resolvedAgentType?` @${o.resolvedAgentType}`:o.agentType?` ${o.agentType}`:"";return r("subagent",`started ${o.model}${i} [${o.subagentId}]`)}case"succeeded":{let i=o.totalCostUsd!==void 0?` ${Fc(o.totalCostUsd)}`:"";return r("subagent",`succeeded ${wo(o.durationMs)} ${o.turnCount} turns ${z_(o.outputBytes)}${i} [${o.subagentId}]`)}case"failed":{let i=o.failureClass==="timeout"?" [timeout]":"";return r("subagent",`FAILED ${o.errorClass}: ${xi(o.errorMessage,80)}${i} [${o.subagentId}]`)}case"cancelled":{let i=o.timeout?" (timeout)":"";return r("subagent",`cancelled (${o.source})${i} [${o.subagentId}]`)}}return null}case"background_agent":{let o=e.payload;switch(o.transition){case"started":return r("bg-agent",`started ${o.model} ${xi(o.label,60)} [${o.jobId}]`);case"completed":return r("bg-agent",`completed ${wo(o.durationMs)} ${z_(o.outputBytes)} [${o.jobId}]`);case"failed":return r("bg-agent",`FAILED ${o.errorClass}: ${xi(o.errorMessage,80)} [${o.jobId}]`);case"cancelled":return r("bg-agent",`cancelled (${o.source}) [${o.jobId}]`);case"joined":return r("bg-agent",`joined ${o.jobStatus} [${o.jobId}]`);case"delivered":return r("bg-agent",`delivered ${o.jobStatus} [${o.jobId}]`)}return null}case"abort":{let o=e.payload,i=o.reason?` ${xi(o.reason,80)}`:"",s=o.cascadedTo.length>0?` cascaded\u2192${o.cascadedTo.length}`:"";return r("abort",`${o.origin}${i}${s}`)}case"compaction":{let o=e.payload,i=o.tokensSavedEstimate!==void 0?` ~${o.tokensSavedEstimate} tok saved`:"";return r("compact",`${o.trigger} ${o.messagesBefore}\u2192${o.messagesAfter} msgs${i}`)}case"closure":{let o=e.payload,i=o.guidance?` \u2014 ${xi(o.guidance,100)}`:"",s=o.lastStopReason?` stop=${o.lastStopReason}`:"",a=Nz(o.finalTokens);return r("closure",`${o.reason} turns=${o.finalTurnCount}${s} ${Fc(o.finalCostUsd)}${a}${i}`)}case"claim":{let o=e.payload;return r("claim",`[${o.source}] "${xi(o.assertion,80)}" conf=${o.confidence} ${o.evidence.length} evidence`)}case"browser_event":{let o=e.payload,i=o.action?` ${o.action}`:"",s=o.urlAfter?` ${o.urlAfter}`:"";return r("browser",`${o.tool}${i} ${o.status}${s}`)}case"budget":{let o=e.payload;return r("budget",`${o.kind} ${Fc(o.runningCostUsd)}/${Fc(o.maxBudgetUsd)}`)}case"session_phase":{let o=e.payload;if(o.phase==="rate_limit"){let l=o.metadata??{},c=l.reason,u=l.status,d=l.source,p=o.durationMs!==void 0?` retry-after ${wo(o.durationMs)}`:"",f=u!==void 0?` ${u}`:"",g=d!==void 0?` (${d})`:"",h=c!==void 0?String(c):"throttled";return r("throttle",`${h}${f}${p}${g}`)}if(o.phase==="ttfb_timeout"){let l=o.metadata?.source,c=l!==void 0?` (${String(l)})`:"",u=o.durationMs!==void 0?` after ${wo(o.durationMs)}`:"",d=o.metadata?.attempt,p=d!==void 0?` #${String(d)}`:"";return r("ttfb-stall",`no first token${u} \u2014 request re-driven${p}${c}`)}if(o.phase==="usage_limit_pause"){let c=(o.metadata??{}).resetsAt,u=c!==void 0?` resets ${c}`:" no reset ts";return r("paused",`usage-limit${u}`)}if(o.phase==="usage_limit_resume"){let l=o.metadata??{},c=o.durationMs!==void 0?` parked ${wo(o.durationMs)}`:"",u=l.hotSwapped===!0?" (hot-swap)":"";return r("resumed",`usage-limit${c}${u}`)}if(o.phase==="overload_pause"){let l=o.metadata??{},c=l.ceilingMs,u=typeof c=="number"?` ceiling ${wo(c)}`:" no ceiling",d=l.surface,p=d!==void 0?` ${String(d)}`:"";return r("paused",`overloaded (529)${u}${p}`)}if(o.phase==="overload_resume"){let l=o.metadata??{},c=o.durationMs!==void 0?` parked ${wo(o.durationMs)}`:"",u=l.outcome,d=u!==void 0?` ${String(u)}`:"";return r("resumed",`overloaded${c}${d}`)}if(o.phase==="compaction_disabled"){let l=o.metadata??{},c=l.wire,u=l.status,d=l.error,p=c!==void 0?` (${c} wire)`:"",f=u!==void 0?` ${u}`:"",g=d!==void 0?` ${d}`:"";return r("compact",`DISABLED for session${p}${f}${g}`)}if(!t.showAll)return null;let i=o.durationMs!==void 0?` ${wo(o.durationMs)}`:"",s=o.model??o.resolvedModel,a=s!==void 0?` ${s}`:"";return r("phase",`${o.phase}${i}${a}`)}case"session_sealed":{let o=e.payload,i=o.subagentCount?` ${o.subagentCount} subagents`:"";return r("SEALED",`${o.status} turns=${o.finalTurnCount} ${Fc(o.finalCostUsd)}${i} (closed ${o.closedAt})`)}default:{let o=e.kind;return r(o,"(unrecognized event kind)")}}}function ACe(e){let t=0,n=0,r=0,o=0,i=0,s=0,a=0,l=null,c=null,u=null,d=null;for(let p of e)switch(p.kind){case"tool_call":p.payload.phase==="completed"&&(t++,p.payload.isError&&n++);break;case"session_phase":p.payload.phase==="rate_limit"&&s++,p.payload.phase==="ttfb_timeout"&&a++,p.payload.phase==="session_init_start"&&(u===null&&p.payload.model!==void 0&&(u=p.payload.model),d===null&&p.payload.resolvedModel!==void 0&&(d=p.payload.resolvedModel));break;case"subagent_lifecycle":p.payload.transition==="started"&&r++;break;case"claim":o++;break;case"hook_decision":p.payload.decision==="block"&&i++;break;case"session_sealed":l=p.payload.status,c=p.payload.finalCostUsd;break;case"closure":c===null&&(c=p.payload.finalCostUsd);break;default:break}return{total:e.length,toolCalls:t,toolErrors:n,subagents:r,claims:o,blocks:i,throttles:s,ttfbStalls:a,sealStatus:l,finalCostUsd:c,model:u,resolvedModel:d}}function CCe(e,t,n,r={}){let{events:o,malformed:i}=n,s=ACe(o),a=new Set;for(let b of o)b.kind==="tool_call"&&b.payload.phase==="completed"&&a.add(b.payload.toolUseId);let l={completedToolIds:a,showAll:r.showAll??!1},c=s.sealStatus!==null?`sealed (${s.sealStatus})`:"unsealed (live or crashed)",u=s.finalCostUsd!==null?` \xB7 ${Fc(s.finalCostUsd)}`:"",d=s.throttles>0?` \xB7 ${s.throttles} throttled`:"",p=s.ttfbStalls>0?` \xB7 ${s.ttfbStalls} ttfb-stall`:"",f=[];if(f.push(`Trace ${e}`),f.push(`File ${t}`),s.model!==null){let b=s.resolvedModel!==null&&s.resolvedModel!==s.model?` \u2192 ${s.resolvedModel}`:"";f.push(`Model ${s.model}${b}`)}f.push(` ${c} \xB7 ${s.total} events \xB7 ${s.toolCalls} tool calls (${s.toolErrors} err) \xB7 ${s.subagents} subagents \xB7 ${s.claims} claims \xB7 ${s.blocks} blocks${d}${p}${u}`),f.push("");let g=[];for(let b of o){let w=xCe(b,l);w!==null&&g.push(w)}let h=r.limit!==void 0&&r.limit>=0&&g.length>r.limit?g.length-r.limit:0;h>0&&(g=g.slice(-r.limit),f.push(` \u2026 ${h} earlier event(s) hidden (raise --limit to see them)`)),g.length===0?f.push(" (no events to display \u2014 try --all, or --json for the raw record)"):f.push(...g),f.push("");let y=[];return i>0&&y.push(`${i} malformed line(s) skipped`),l.showAll||y.push("use --all for phase/started events, --json for raw"),y.length>0&&f.push(y.join(" \xB7 ")),f.join(`
2045
+ `)}catch(r){J(r)}})}import{readFile as h6,readdir as bCe,stat as wCe}from"node:fs/promises";import{join as KS}from"node:path";G();Ul();function J_(){return KS(fe(),"witness")}async function y6(){let e=J_(),t;try{t=await bCe(e)}catch(r){if(r.code==="ENOENT")return[];throw r}let n=[];for(let r of t){let o=KS(e,r,"trace.jsonl");try{let i=await wCe(o);i.isFile()&&n.push({sessionId:r,tracePath:o,mtimeMs:i.mtimeMs,exists:!0})}catch{}}return n.sort((r,o)=>o.mtimeMs-r.mtimeMs),n}async function SCe(){return(await y6())[0]?.sessionId??null}function vCe(e){if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.kind=="string"&&typeof t.seq=="number"&&typeof t.payload=="object"&&t.payload!==null}function kCe(e){let t=[],n=0;for(let r of e.split(`
2046
+ `))if(r.trim()!=="")try{let o=JSON.parse(r);vCe(o)?t.push(o):n++}catch{n++}return{events:t,malformed:n}}async function f6(e){let t=e;if(e==="latest"){let o=await SCe();if(o===null)throw new Error(`No traces found under ${J_()}. Run an agent session first, or pass an explicit session id (see \`afk trace list\`).`);t=o}let n=KS(nr(t),"trace.jsonl"),r=await g6(n);if(r===null){let o=await TCe(t);if(o.kind==="disabled")throw new Error(`Session "${t}" ran with tracing disabled \u2014 its ledger records traceLabel: null, so no witness trace was written (tracing is off when AFK_TRACE_DISABLED=1).`);if(o.kind==="label"&&o.label!==t)try{let i=KS(nr(o.label),"trace.jsonl"),s=await g6(i);s!==null&&(n=i,r=s)}catch{}}if(r===null)throw new Error(`No trace found for session "${t}" at ${n}. See \`afk trace list\` for available sessions.`);return{sessionId:t,tracePath:n,...kCe(r)}}async function g6(e){try{return await h6(e,"utf8")}catch(t){if(t.code==="ENOENT")return null;throw t}}async function TCe(e){try{for await(let t of Bl(e))if(t.kind==="meta")return typeof t.traceLabel=="string"&&t.traceLabel.length>0?{kind:"label",label:t.traceLabel}:t.traceLabel===null?{kind:"disabled"}:{kind:"none"}}catch{}return{kind:"none"}}function wo(e){if(e<1e3)return`${e}ms`;if(e<6e4)return`${(e/1e3).toFixed(1)}s`;let t=Math.floor(e/6e4),n=Math.round(e%6e4/1e3);return`${t}m${n}s`}function z_(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function Fc(e){return`$${e.toFixed(4)}`}function ECe(e){return e.length>=19?e.slice(11,19):e}function xi(e,t){return e.length>t?`${e.slice(0,t-1)}\u2026`:e}function RCe(e){return e.length>=9?e:e+" ".repeat(9-e.length)}function xCe(e,t){let n=ECe(e.ts),r=(o,i)=>` ${n} ${RCe(o)} ${i}`;switch(e.kind){case"tool_call":{let o=e.payload;if(o.phase==="started"){let l=!t.completedToolIds.has(o.toolUseId);if(!t.showAll&&!l)return null;let c=o.subagentId?` [${o.subagentId}]`:"",u=l?"started (no completion recorded)":"started";return r("tool",`${o.name} ${u}${c}`)}let i=o.isError?"ERR":"ok",s=o.truncated?" (truncated)":"",a=o.subagentId?` [${o.subagentId}]`:"";return r("tool",`${o.name} ${i} ${wo(o.durationMs)} ${z_(o.resultBytes)}${s}${a}`)}case"hook_decision":{let o=e.payload;if(o.decision===void 0)return null;if(o.decision==="block"){let s=o.blockedTool?` ${o.blockedTool}`:"",a=o.reason?` (${xi(o.reason,80)})`:"";return r("hook",`BLOCK ${o.hookEvent}${s}${a}`)}let i=o.reason?` (${xi(o.reason,80)})`:"";return r("hook",`approve ${o.hookEvent}${i}`)}case"subagent_lifecycle":{let o=e.payload;switch(o.transition){case"started":{let i=o.resolvedAgentType?` @${o.resolvedAgentType}`:o.agentType?` ${o.agentType}`:"";return r("subagent",`started ${o.model}${i} [${o.subagentId}]`)}case"succeeded":{let i=o.totalCostUsd!==void 0?` ${Fc(o.totalCostUsd)}`:"";return r("subagent",`succeeded ${wo(o.durationMs)} ${o.turnCount} turns ${z_(o.outputBytes)}${i} [${o.subagentId}]`)}case"failed":{let i=o.failureClass==="timeout"?" [timeout]":"";return r("subagent",`FAILED ${o.errorClass}: ${xi(o.errorMessage,80)}${i} [${o.subagentId}]`)}case"cancelled":{let i=o.timeout?" (timeout)":"";return r("subagent",`cancelled (${o.source})${i} [${o.subagentId}]`)}}return null}case"background_agent":{let o=e.payload;switch(o.transition){case"started":return r("bg-agent",`started ${o.model} ${xi(o.label,60)} [${o.jobId}]`);case"completed":return r("bg-agent",`completed ${wo(o.durationMs)} ${z_(o.outputBytes)} [${o.jobId}]`);case"failed":return r("bg-agent",`FAILED ${o.errorClass}: ${xi(o.errorMessage,80)} [${o.jobId}]`);case"cancelled":return r("bg-agent",`cancelled (${o.source}) [${o.jobId}]`);case"joined":return r("bg-agent",`joined ${o.jobStatus} [${o.jobId}]`);case"delivered":return r("bg-agent",`delivered ${o.jobStatus} [${o.jobId}]`)}return null}case"abort":{let o=e.payload,i=o.reason?` ${xi(o.reason,80)}`:"",s=o.cascadedTo.length>0?` cascaded\u2192${o.cascadedTo.length}`:"";return r("abort",`${o.origin}${i}${s}`)}case"compaction":{let o=e.payload,i=o.tokensSavedEstimate!==void 0?` ~${o.tokensSavedEstimate} tok saved`:"";return r("compact",`${o.trigger} ${o.messagesBefore}\u2192${o.messagesAfter} msgs${i}`)}case"closure":{let o=e.payload,i=o.guidance?` \u2014 ${xi(o.guidance,100)}`:"",s=o.lastStopReason?` stop=${o.lastStopReason}`:"",a=Nz(o.finalTokens);return r("closure",`${o.reason} turns=${o.finalTurnCount}${s} ${Fc(o.finalCostUsd)}${a}${i}`)}case"claim":{let o=e.payload;return r("claim",`[${o.source}] "${xi(o.assertion,80)}" conf=${o.confidence} ${o.evidence.length} evidence`)}case"browser_event":{let o=e.payload,i=o.action?` ${o.action}`:"",s=o.urlAfter?` ${o.urlAfter}`:"";return r("browser",`${o.tool}${i} ${o.status}${s}`)}case"budget":{let o=e.payload;return r("budget",`${o.kind} ${Fc(o.runningCostUsd)}/${Fc(o.maxBudgetUsd)}`)}case"session_phase":{let o=e.payload;if(o.phase==="rate_limit"){let l=o.metadata??{},c=l.reason,u=l.status,d=l.source,p=o.durationMs!==void 0?` retry-after ${wo(o.durationMs)}`:"",f=u!==void 0?` ${u}`:"",g=d!==void 0?` (${d})`:"",h=c!==void 0?String(c):"throttled";return r("throttle",`${h}${f}${p}${g}`)}if(o.phase==="ttfb_timeout"){let l=o.metadata?.source,c=l!==void 0?` (${String(l)})`:"",u=o.durationMs!==void 0?` after ${wo(o.durationMs)}`:"",d=o.metadata?.attempt,p=d!==void 0?` #${String(d)}`:"";return r("ttfb-stall",`no first token${u} \u2014 request re-driven${p}${c}`)}if(o.phase==="usage_limit_pause"){let c=(o.metadata??{}).resetsAt,u=c!==void 0?` resets ${c}`:" no reset ts";return r("paused",`usage-limit${u}`)}if(o.phase==="usage_limit_resume"){let l=o.metadata??{},c=o.durationMs!==void 0?` parked ${wo(o.durationMs)}`:"",u=l.hotSwapped===!0?" (hot-swap)":"";return r("resumed",`usage-limit${c}${u}`)}if(o.phase==="overload_pause"){let l=o.metadata??{},c=l.ceilingMs,u=typeof c=="number"?` ceiling ${wo(c)}`:" no ceiling",d=l.surface,p=d!==void 0?` ${String(d)}`:"";return r("paused",`overloaded (529)${u}${p}`)}if(o.phase==="overload_resume"){let l=o.metadata??{},c=o.durationMs!==void 0?` parked ${wo(o.durationMs)}`:"",u=l.outcome,d=u!==void 0?` ${String(u)}`:"";return r("resumed",`overloaded${c}${d}`)}if(o.phase==="compaction_disabled"){let l=o.metadata??{},c=l.wire,u=l.status,d=l.error,p=c!==void 0?` (${c} wire)`:"",f=u!==void 0?` ${u}`:"",g=d!==void 0?` ${d}`:"";return r("compact",`DISABLED for session${p}${f}${g}`)}if(!t.showAll)return null;let i=o.durationMs!==void 0?` ${wo(o.durationMs)}`:"",s=o.model??o.resolvedModel,a=s!==void 0?` ${s}`:"";return r("phase",`${o.phase}${i}${a}`)}case"session_sealed":{let o=e.payload,i=o.subagentCount?` ${o.subagentCount} subagents`:"";return r("SEALED",`${o.status} turns=${o.finalTurnCount} ${Fc(o.finalCostUsd)}${i} (closed ${o.closedAt})`)}default:{let o=e.kind;return r(o,"(unrecognized event kind)")}}}function ACe(e){let t=0,n=0,r=0,o=0,i=0,s=0,a=0,l=null,c=null,u=null,d=null;for(let p of e)switch(p.kind){case"tool_call":p.payload.phase==="completed"&&(t++,p.payload.isError&&n++);break;case"session_phase":p.payload.phase==="rate_limit"&&s++,p.payload.phase==="ttfb_timeout"&&a++,p.payload.phase==="session_init_start"&&(u===null&&p.payload.model!==void 0&&(u=p.payload.model),d===null&&p.payload.resolvedModel!==void 0&&(d=p.payload.resolvedModel));break;case"subagent_lifecycle":p.payload.transition==="started"&&r++;break;case"claim":o++;break;case"hook_decision":p.payload.decision==="block"&&i++;break;case"session_sealed":l=p.payload.status,c=p.payload.finalCostUsd;break;case"closure":c===null&&(c=p.payload.finalCostUsd);break;default:break}return{total:e.length,toolCalls:t,toolErrors:n,subagents:r,claims:o,blocks:i,throttles:s,ttfbStalls:a,sealStatus:l,finalCostUsd:c,model:u,resolvedModel:d}}function CCe(e,t,n,r={}){let{events:o,malformed:i}=n,s=ACe(o),a=new Set;for(let b of o)b.kind==="tool_call"&&b.payload.phase==="completed"&&a.add(b.payload.toolUseId);let l={completedToolIds:a,showAll:r.showAll??!1},c=s.sealStatus!==null?`sealed (${s.sealStatus})`:"unsealed (live or crashed)",u=s.finalCostUsd!==null?` \xB7 ${Fc(s.finalCostUsd)}`:"",d=s.throttles>0?` \xB7 ${s.throttles} throttled`:"",p=s.ttfbStalls>0?` \xB7 ${s.ttfbStalls} ttfb-stall`:"",f=[];if(f.push(`Trace ${e}`),f.push(`File ${t}`),s.model!==null){let b=s.resolvedModel!==null&&s.resolvedModel!==s.model?` \u2192 ${s.resolvedModel}`:"";f.push(`Model ${s.model}${b}`)}f.push(` ${c} \xB7 ${s.total} events \xB7 ${s.toolCalls} tool calls (${s.toolErrors} err) \xB7 ${s.subagents} subagents \xB7 ${s.claims} claims \xB7 ${s.blocks} blocks${d}${p}${u}`),f.push("");let g=[];for(let b of o){let w=xCe(b,l);w!==null&&g.push(w)}let h=r.limit!==void 0&&r.limit>=0&&g.length>r.limit?g.length-r.limit:0;h>0&&(g=g.slice(-r.limit),f.push(` \u2026 ${h} earlier event(s) hidden (raise --limit to see them)`)),g.length===0?f.push(" (no events to display \u2014 try --all, or --json for the raw record)"):f.push(...g),f.push("");let y=[];return i>0&&y.push(`${i} malformed line(s) skipped`),l.showAll||y.push("use --all for phase/started events, --json for raw"),y.length>0&&f.push(y.join(" \xB7 ")),f.join(`
2047
2047
  `)+`
2048
- `}function b5(e){let t=e.command("trace").description(`Inspect the witness-layer trace of a session \u2014 the durable record of
2048
+ `}function b6(e){let t=e.command("trace").description(`Inspect the witness-layer trace of a session \u2014 the durable record of
2049
2049
  everything the agent did. Reads ~/.afk/state/witness/<session>/trace.jsonl.`);t.command("show [session]").description(`Pretty-print a session's trace for humans. [session] is a session id
2050
- or "latest" (the default) \u2014 the most recently written trace.`).option("--all","Include low-signal events (latency phases, paired tool starts)",!1).option("--json","Emit the raw NDJSON record unchanged (for piping to jq)",!1).option("-n, --limit <number>","Show only the last N events").action(async(n,r)=>{try{let o=n??"latest";if(r.json){let{tracePath:a}=await f5(o),l=await h5(a,"utf8");process.stdout.write(l.endsWith(`
2050
+ or "latest" (the default) \u2014 the most recently written trace.`).option("--all","Include low-signal events (latency phases, paired tool starts)",!1).option("--json","Emit the raw NDJSON record unchanged (for piping to jq)",!1).option("-n, --limit <number>","Show only the last N events").action(async(n,r)=>{try{let o=n??"latest";if(r.json){let{tracePath:a}=await f6(o),l=await h6(a,"utf8");process.stdout.write(l.endsWith(`
2051
2051
  `)?l:l+`
2052
- `);return}let i=await f5(o),s;if(r.limit!==void 0){let a=parseInt(r.limit,10);!Number.isNaN(a)&&a>=0&&(s=a)}process.stdout.write(CCe(i.sessionId,i.tracePath,i,{showAll:r.all,...s!==void 0?{limit:s}:{}}))}catch(o){J(o)}}),t.command("list").description("List sessions that have a trace, most recent first").option("-n, --max <number>","Maximum sessions to show","20").action(async n=>{try{let r=Math.min(200,Math.max(1,parseInt(n.max,10)||20)),o=await y5();if(o.length===0){process.stdout.write(`No traces found under ${J_()}
2052
+ `);return}let i=await f6(o),s;if(r.limit!==void 0){let a=parseInt(r.limit,10);!Number.isNaN(a)&&a>=0&&(s=a)}process.stdout.write(CCe(i.sessionId,i.tracePath,i,{showAll:r.all,...s!==void 0?{limit:s}:{}}))}catch(o){J(o)}}),t.command("list").description("List sessions that have a trace, most recent first").option("-n, --max <number>","Maximum sessions to show","20").action(async n=>{try{let r=Math.min(200,Math.max(1,parseInt(n.max,10)||20)),o=await y6();if(o.length===0){process.stdout.write(`No traces found under ${J_()}
2053
2053
  `);return}for(let i of o.slice(0,r)){let s=new Date(i.mtimeMs).toISOString().replace("T"," ").slice(0,19);process.stdout.write(`${s} ${i.sessionId}
2054
- `)}}catch(r){J(r)}})}import{execFileSync as zCe}from"child_process";import{existsSync as JCe}from"fs";G();import{homedir as w5}from"os";import{join as V_}from"path";function zt(e){return`com.afk.${e}`}function Y_(e=w5()){return V_(e,"Library","LaunchAgents")}function Or(e,t=w5()){return V_(Y_(t),`${zt(e)}.plist`)}function Lc(e){return V_(To(),`service-${e}.log`)}function sa(){return`gui/${process.getuid?.()??501}`}var So=8e3;import{execFileSync as zS}from"child_process";import{existsSync as X_,mkdirSync as E5,readFileSync as LCe,renameSync as NCe,rmSync as BCe,unlinkSync as UCe,writeFileSync as jCe}from"fs";import{homedir as HCe}from"os";import{dirname as WCe}from"path";import{execFileSync as _Ce}from"child_process";import{existsSync as S5,realpathSync as v5}from"fs";import{homedir as ICe}from"os";import{delimiter as PCe,dirname as MCe,resolve as OCe}from"path";function Ai(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function k5(e){let t=[];t.push('<?xml version="1.0" encoding="UTF-8"?>'),t.push('<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">'),t.push('<plist version="1.0">'),t.push("<dict>"),t.push(" <key>Label</key>"),t.push(` <string>${Ai(e.label)}</string>`),t.push(" <key>ProgramArguments</key>"),t.push(" <array>");for(let n of e.programArguments)t.push(` <string>${Ai(n)}</string>`);if(t.push(" </array>"),t.push(" <key>WorkingDirectory</key>"),t.push(` <string>${Ai(e.workingDirectory)}</string>`),t.push(" <key>StandardOutPath</key>"),t.push(` <string>${Ai(e.standardOutPath)}</string>`),t.push(" <key>StandardErrorPath</key>"),t.push(` <string>${Ai(e.standardErrorPath)}</string>`),t.push(" <key>RunAtLoad</key>"),t.push(" <true/>"),t.push(" <key>KeepAlive</key>"),t.push(" <true/>"),t.push(" <key>ProcessType</key>"),t.push(" <string>Interactive</string>"),e.watchPaths&&e.watchPaths.length>0){t.push(" <key>WatchPaths</key>"),t.push(" <array>");for(let n of e.watchPaths)t.push(` <string>${Ai(n)}</string>`);t.push(" </array>")}if(e.environmentVariables&&Object.keys(e.environmentVariables).length>0){t.push(" <key>EnvironmentVariables</key>"),t.push(" <dict>");let n=Object.keys(e.environmentVariables).sort();for(let r of n){let o=e.environmentVariables[r]??"";t.push(` <key>${Ai(r)}</key>`),t.push(` <string>${Ai(o)}</string>`)}t.push(" </dict>")}return t.push("</dict>"),t.push("</plist>"),t.join(`
2054
+ `)}}catch(r){J(r)}})}import{execFileSync as zCe}from"child_process";import{existsSync as JCe}from"fs";G();import{homedir as w6}from"os";import{join as V_}from"path";function zt(e){return`com.afk.${e}`}function Y_(e=w6()){return V_(e,"Library","LaunchAgents")}function Or(e,t=w6()){return V_(Y_(t),`${zt(e)}.plist`)}function Lc(e){return V_(To(),`service-${e}.log`)}function sa(){return`gui/${process.getuid?.()??501}`}var So=8e3;import{execFileSync as zS}from"child_process";import{existsSync as X_,mkdirSync as E6,readFileSync as LCe,renameSync as NCe,rmSync as BCe,unlinkSync as UCe,writeFileSync as jCe}from"fs";import{homedir as HCe}from"os";import{dirname as WCe}from"path";import{execFileSync as _Ce}from"child_process";import{existsSync as S6,realpathSync as v6}from"fs";import{homedir as ICe}from"os";import{delimiter as PCe,dirname as MCe,resolve as OCe}from"path";function Ai(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function k6(e){let t=[];t.push('<?xml version="1.0" encoding="UTF-8"?>'),t.push('<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">'),t.push('<plist version="1.0">'),t.push("<dict>"),t.push(" <key>Label</key>"),t.push(` <string>${Ai(e.label)}</string>`),t.push(" <key>ProgramArguments</key>"),t.push(" <array>");for(let n of e.programArguments)t.push(` <string>${Ai(n)}</string>`);if(t.push(" </array>"),t.push(" <key>WorkingDirectory</key>"),t.push(` <string>${Ai(e.workingDirectory)}</string>`),t.push(" <key>StandardOutPath</key>"),t.push(` <string>${Ai(e.standardOutPath)}</string>`),t.push(" <key>StandardErrorPath</key>"),t.push(` <string>${Ai(e.standardErrorPath)}</string>`),t.push(" <key>RunAtLoad</key>"),t.push(" <true/>"),t.push(" <key>KeepAlive</key>"),t.push(" <true/>"),t.push(" <key>ProcessType</key>"),t.push(" <string>Interactive</string>"),e.watchPaths&&e.watchPaths.length>0){t.push(" <key>WatchPaths</key>"),t.push(" <array>");for(let n of e.watchPaths)t.push(` <string>${Ai(n)}</string>`);t.push(" </array>")}if(e.environmentVariables&&Object.keys(e.environmentVariables).length>0){t.push(" <key>EnvironmentVariables</key>"),t.push(" <dict>");let n=Object.keys(e.environmentVariables).sort();for(let r of n){let o=e.environmentVariables[r]??"";t.push(` <key>${Ai(r)}</key>`),t.push(` <string>${Ai(o)}</string>`)}t.push(" </dict>")}return t.push("</dict>"),t.push("</plist>"),t.join(`
2055
2055
  `)+`
2056
- `}var $Ce=["/usr/local/bin","/opt/homebrew/bin","/usr/bin","/bin","/usr/sbin","/sbin"];function GS(e=process.execPath){let t=MCe(e),n=new Set,r=[];for(let o of[t,...$Ce])o.length>0&&!n.has(o)&&(n.add(o),r.push(o));return r.join(PCe)}function DCe(e=["/usr/local/bin/afk","/opt/homebrew/bin/afk"],t=S5,n=FCe,r=v5){let o=process.argv[1];if(o)try{let s=r(o);if(T5.some(a=>s.startsWith(a))&&t(s))return s}catch{}let i=n();if(i&&t(i))return i;for(let s of e)if(t(s))return s;throw new Error(`Could not locate the 'afk' binary. Searched: ${e.join(", ")}. Install it globally first (e.g. 'pnpm install -g agent-afk' or via Homebrew).`)}var T5=["/usr/local/bin/","/opt/homebrew/bin/","/usr/bin/","/opt/local/bin/"];function FCe(){try{let e=_Ce("which",["afk"],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim();if(!e)return;let t;try{t=v5(e)}catch{return}return T5.some(n=>t.startsWith(n))?t:void 0}catch{return}}function im(e,t=S5){if(e==="telegram"){let r=B_();if(r.endsWith(".ts"))throw new Error(`Refusing to install telegram service pointing at TypeScript source (${r}). Run 'pnpm build' first so the compiled entrypoint exists, or install agent-afk globally (e.g. 'pnpm install -g agent-afk').`);if(!t(r))throw new Error(`Telegram entrypoint does not exist on disk: ${r}. Run 'pnpm build' to compile it, or install agent-afk globally.`);return[process.execPath,r]}return[DCe(),"daemon"]}function qS(e,t){let n=im(e,t),r=e==="telegram"?n[1]:void 0;if(!r)return;let o=OCe(r),i=ICe();if(o.startsWith(i)&&!(o.includes("/node_modules/")||o.includes("/homebrew/")))return[o]}function R5(e,t={}){let n=Or(e);if(X_(n))return{kind:"already-installed",plistPath:n,label:zt(e)};let r;try{r=im(e,t._entrypointExistsCheck)}catch(u){return{kind:"failed",reason:u.message}}let o=t.noWatch?void 0:qS(e,t._entrypointExistsCheck),i=Lc(e);E5(Y_(),{recursive:!0}),E5(WCe(i),{recursive:!0});let s={PATH:GS(),...t.environment??{}},a={label:zt(e),programArguments:r,workingDirectory:HCe(),standardOutPath:i,standardErrorPath:i,...o?{watchPaths:o}:{},environmentVariables:s},l=k5(a),c=`${n}.tmp`;try{jCe(c,l,{encoding:"utf-8",flag:"wx",mode:384})}catch(u){return{kind:"failed",reason:`Failed to write plist (tmp ${c}): ${u.message}`}}try{NCe(c,n)}catch(u){try{UCe(c)}catch{}return{kind:"failed",reason:`Failed to install plist (rename ${c} \u2192 ${n}): ${u.message}`}}if(t.skipBootstrap)return{kind:"installed",plistPath:n,label:zt(e),watchPathsActive:!!o};try{zS("launchctl",["bootstrap",sa(),n],{stdio:["ignore","pipe","pipe"],timeout:So})}catch(u){let d=u.message;if(u.code==="EALREADY"||/\b37\b/.test(d))return{kind:"failed",reason:`Service already loaded \u2014 run 'afk service restart ${e}' to reload with the new plist.`};if(/already bootstrapped|already loaded/i.test(d)){let p="";try{zS("launchctl",["bootout",`${sa()}/${zt(e)}`],{stdio:["ignore","pipe","pipe"],timeout:So})}catch(f){p=f.message}try{zS("launchctl",["bootstrap",sa(),n],{stdio:["ignore","pipe","pipe"],timeout:So})}catch(f){let g=f.message;return{kind:"failed",reason:`Bootstrap failed: ${p?`${g} (prior bootout: ${p})`:g}`}}}else return{kind:"failed",reason:`Bootstrap failed: ${d}`}}return{kind:"installed",plistPath:n,label:zt(e),watchPathsActive:!!o}}function x5(e,t={}){let n=Or(e);if(!X_(n))return{kind:"not-installed",plistPath:n};if(!t.skipBootout)try{zS("launchctl",["bootout",`${sa()}/${zt(e)}`],{stdio:"ignore",timeout:So})}catch{}try{BCe(n,{force:!0})}catch(r){return{kind:"failed",reason:`Failed to remove plist: ${r.message}`}}return{kind:"uninstalled",plistPath:n}}function A5(e){let t=Or(e);if(X_(t))return LCe(t,"utf-8")}import{execFileSync as KCe}from"child_process";import{existsSync as GCe}from"fs";function qCe(e,t){let n=e.trim();if(n.startsWith("[")||n.startsWith("{")){try{let r=JSON.parse(n),o=Array.isArray(r)?r:[r];for(let i of o){if(typeof i!="object"||i===null)continue;let s=i;if(s.Label!==t)continue;let a={};return typeof s.PID=="number"&&Number.isFinite(s.PID)&&(a.pid=s.PID),typeof s.LastExitStatus=="number"&&Number.isFinite(s.LastExitStatus)&&(a.lastExitStatus=s.LastExitStatus),a}}catch{}return}for(let r of n.split(`
2057
- `)){let o=r.split(" "),i=o.length>=3?o:r.trim().split(/\s+/);if(i.length<3||i[2]?.trim()!==t)continue;let s=i[0]?.trim()??"-",a=i[1]?.trim()??"0",l={};if(s!=="-"&&s!==""){let u=Number.parseInt(s,10);Number.isFinite(u)&&(l.pid=u)}let c=Number.parseInt(a,10);return Number.isFinite(c)&&(l.lastExitStatus=c),l}}function C5(e){let t=Or(e),n={name:e,label:zt(e),installed:GCe(t),plistPath:t,logFile:Lc(e)};if(!n.installed)return n;try{let r=KCe("launchctl",["list"],{encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:So}),o=qCe(r,n.label);o&&(o.pid!==void 0&&(n.pid=o.pid),o.lastExitStatus!==void 0&&(n.lastExitStatus=o.lastExitStatus))}catch{}return n}var _5={backend:"launchd",configKind:"LaunchAgent plist",install(e,t={}){let n=R5(e,{noWatch:t.noWatch??!1,skipBootstrap:t.dryRun??!1,...t.environment?{environment:t.environment}:{}});if(n.kind==="already-installed")return{kind:"already-installed",configPath:n.plistPath,label:n.label};if(n.kind==="failed")return{kind:"failed",reason:n.reason};let r=[];if(t.dryRun){let o=process.getuid?.()??501;r.push("(dry-run) launchctl bootstrap was skipped; service is NOT yet running."),r.push(`Load manually: launchctl bootstrap gui/${o} ${n.plistPath}`)}return{kind:"installed",configPath:n.plistPath,label:n.label,autoRestartOnRebuild:n.watchPathsActive,...r.length>0?{notes:r}:{}}},uninstall(e){let t=x5(e);return t.kind==="failed"?{kind:"failed",reason:t.reason}:{kind:t.kind,configPath:t.plistPath}},status(e){let t=C5(e);return{name:t.name,label:t.label,installed:t.installed,configPath:t.plistPath,logFile:t.logFile,...t.pid!==void 0?{pid:t.pid}:{},...t.lastExitStatus!==void 0?{lastExitStatus:t.lastExitStatus}:{}}},restart(e){if(!this.isInstalled(e))return{kind:"not-installed",configPath:Or(e)};if(typeof process.getuid!="function")return{kind:"failed",reason:"process.getuid is unavailable \u2014 restart requires a POSIX system."};try{return zCe("launchctl",["kickstart","-k",`${sa()}/${zt(e)}`],{stdio:["ignore","pipe","pipe"],timeout:So}),{kind:"restarted",label:zt(e)}}catch(t){return{kind:"failed",reason:t.message}}},isInstalled(e){return JCe(Or(e))},configPath(e){return Or(e)},logPath(e){return Lc(e)},label(e){return zt(e)},readConfigFile(e){return A5(e)}};import{execFileSync as u_e}from"child_process";import{existsSync as U5}from"fs";G();import{homedir as JS}from"os";import{join as sm}from"path";function am(e=JS()){return sm(e,".config","systemd","user")}function Jt(e){return`afk-${e}.service`}function VS(e){return`afk-${e}.path`}function Q_(e){return`afk-${e}-restart.service`}function Zn(e,t=JS()){return sm(am(t),Jt(e))}function YS(e,t=JS()){return sm(am(t),VS(e))}function XS(e,t=JS()){return sm(am(t),Q_(e))}function lm(e){return Jt(e)}function Nc(e){return sm(To(),`service-${e}.log`)}var Bc=8e3;import{execFileSync as XCe}from"child_process";import{existsSync as Uc,mkdirSync as $5,readFileSync as QCe,renameSync as ZCe,rmSync as QS,unlinkSync as e_e,writeFileSync as t_e}from"fs";import{homedir as n_e}from"os";import{dirname as r_e}from"path";function I5(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/%/g,"%%")}function VCe(e){return`"${I5(e)}"`}function YCe(e){return I5(e)}function P5(e){let t=[];if(t.push("[Unit]"),t.push(`Description=${e.description}`),t.push("After=network-online.target"),t.push("Wants=network-online.target"),t.push(""),t.push("[Service]"),t.push("Type=simple"),t.push(`ExecStart=${e.execStart.map(VCe).join(" ")}`),t.push(`WorkingDirectory=${e.workingDirectory}`),t.push("Restart=always"),t.push("RestartSec=2"),t.push(`StandardOutput=append:${e.logFile}`),t.push(`StandardError=append:${e.logFile}`),e.environmentVariables&&Object.keys(e.environmentVariables).length>0)for(let n of Object.keys(e.environmentVariables).sort()){let r=e.environmentVariables[n]??"";t.push(`Environment="${n}=${YCe(r)}"`)}return t.push(""),t.push("[Install]"),t.push("WantedBy=default.target"),t.join(`
2056
+ `}var $Ce=["/usr/local/bin","/opt/homebrew/bin","/usr/bin","/bin","/usr/sbin","/sbin"];function GS(e=process.execPath){let t=MCe(e),n=new Set,r=[];for(let o of[t,...$Ce])o.length>0&&!n.has(o)&&(n.add(o),r.push(o));return r.join(PCe)}function DCe(e=["/usr/local/bin/afk","/opt/homebrew/bin/afk"],t=S6,n=FCe,r=v6){let o=process.argv[1];if(o)try{let s=r(o);if(T6.some(a=>s.startsWith(a))&&t(s))return s}catch{}let i=n();if(i&&t(i))return i;for(let s of e)if(t(s))return s;throw new Error(`Could not locate the 'afk' binary. Searched: ${e.join(", ")}. Install it globally first (e.g. 'pnpm install -g agent-afk' or via Homebrew).`)}var T6=["/usr/local/bin/","/opt/homebrew/bin/","/usr/bin/","/opt/local/bin/"];function FCe(){try{let e=_Ce("which",["afk"],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim();if(!e)return;let t;try{t=v6(e)}catch{return}return T6.some(n=>t.startsWith(n))?t:void 0}catch{return}}function im(e,t=S6){if(e==="telegram"){let r=B_();if(r.endsWith(".ts"))throw new Error(`Refusing to install telegram service pointing at TypeScript source (${r}). Run 'pnpm build' first so the compiled entrypoint exists, or install agent-afk globally (e.g. 'pnpm install -g agent-afk').`);if(!t(r))throw new Error(`Telegram entrypoint does not exist on disk: ${r}. Run 'pnpm build' to compile it, or install agent-afk globally.`);return[process.execPath,r]}return[DCe(),"daemon"]}function qS(e,t){let n=im(e,t),r=e==="telegram"?n[1]:void 0;if(!r)return;let o=OCe(r),i=ICe();if(o.startsWith(i)&&!(o.includes("/node_modules/")||o.includes("/homebrew/")))return[o]}function R6(e,t={}){let n=Or(e);if(X_(n))return{kind:"already-installed",plistPath:n,label:zt(e)};let r;try{r=im(e,t._entrypointExistsCheck)}catch(u){return{kind:"failed",reason:u.message}}let o=t.noWatch?void 0:qS(e,t._entrypointExistsCheck),i=Lc(e);E6(Y_(),{recursive:!0}),E6(WCe(i),{recursive:!0});let s={PATH:GS(),...t.environment??{}},a={label:zt(e),programArguments:r,workingDirectory:HCe(),standardOutPath:i,standardErrorPath:i,...o?{watchPaths:o}:{},environmentVariables:s},l=k6(a),c=`${n}.tmp`;try{jCe(c,l,{encoding:"utf-8",flag:"wx",mode:384})}catch(u){return{kind:"failed",reason:`Failed to write plist (tmp ${c}): ${u.message}`}}try{NCe(c,n)}catch(u){try{UCe(c)}catch{}return{kind:"failed",reason:`Failed to install plist (rename ${c} \u2192 ${n}): ${u.message}`}}if(t.skipBootstrap)return{kind:"installed",plistPath:n,label:zt(e),watchPathsActive:!!o};try{zS("launchctl",["bootstrap",sa(),n],{stdio:["ignore","pipe","pipe"],timeout:So})}catch(u){let d=u.message;if(u.code==="EALREADY"||/\b37\b/.test(d))return{kind:"failed",reason:`Service already loaded \u2014 run 'afk service restart ${e}' to reload with the new plist.`};if(/already bootstrapped|already loaded/i.test(d)){let p="";try{zS("launchctl",["bootout",`${sa()}/${zt(e)}`],{stdio:["ignore","pipe","pipe"],timeout:So})}catch(f){p=f.message}try{zS("launchctl",["bootstrap",sa(),n],{stdio:["ignore","pipe","pipe"],timeout:So})}catch(f){let g=f.message;return{kind:"failed",reason:`Bootstrap failed: ${p?`${g} (prior bootout: ${p})`:g}`}}}else return{kind:"failed",reason:`Bootstrap failed: ${d}`}}return{kind:"installed",plistPath:n,label:zt(e),watchPathsActive:!!o}}function x6(e,t={}){let n=Or(e);if(!X_(n))return{kind:"not-installed",plistPath:n};if(!t.skipBootout)try{zS("launchctl",["bootout",`${sa()}/${zt(e)}`],{stdio:"ignore",timeout:So})}catch{}try{BCe(n,{force:!0})}catch(r){return{kind:"failed",reason:`Failed to remove plist: ${r.message}`}}return{kind:"uninstalled",plistPath:n}}function A6(e){let t=Or(e);if(X_(t))return LCe(t,"utf-8")}import{execFileSync as KCe}from"child_process";import{existsSync as GCe}from"fs";function qCe(e,t){let n=e.trim();if(n.startsWith("[")||n.startsWith("{")){try{let r=JSON.parse(n),o=Array.isArray(r)?r:[r];for(let i of o){if(typeof i!="object"||i===null)continue;let s=i;if(s.Label!==t)continue;let a={};return typeof s.PID=="number"&&Number.isFinite(s.PID)&&(a.pid=s.PID),typeof s.LastExitStatus=="number"&&Number.isFinite(s.LastExitStatus)&&(a.lastExitStatus=s.LastExitStatus),a}}catch{}return}for(let r of n.split(`
2057
+ `)){let o=r.split(" "),i=o.length>=3?o:r.trim().split(/\s+/);if(i.length<3||i[2]?.trim()!==t)continue;let s=i[0]?.trim()??"-",a=i[1]?.trim()??"0",l={};if(s!=="-"&&s!==""){let u=Number.parseInt(s,10);Number.isFinite(u)&&(l.pid=u)}let c=Number.parseInt(a,10);return Number.isFinite(c)&&(l.lastExitStatus=c),l}}function C6(e){let t=Or(e),n={name:e,label:zt(e),installed:GCe(t),plistPath:t,logFile:Lc(e)};if(!n.installed)return n;try{let r=KCe("launchctl",["list"],{encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:So}),o=qCe(r,n.label);o&&(o.pid!==void 0&&(n.pid=o.pid),o.lastExitStatus!==void 0&&(n.lastExitStatus=o.lastExitStatus))}catch{}return n}var _6={backend:"launchd",configKind:"LaunchAgent plist",install(e,t={}){let n=R6(e,{noWatch:t.noWatch??!1,skipBootstrap:t.dryRun??!1,...t.environment?{environment:t.environment}:{}});if(n.kind==="already-installed")return{kind:"already-installed",configPath:n.plistPath,label:n.label};if(n.kind==="failed")return{kind:"failed",reason:n.reason};let r=[];if(t.dryRun){let o=process.getuid?.()??501;r.push("(dry-run) launchctl bootstrap was skipped; service is NOT yet running."),r.push(`Load manually: launchctl bootstrap gui/${o} ${n.plistPath}`)}return{kind:"installed",configPath:n.plistPath,label:n.label,autoRestartOnRebuild:n.watchPathsActive,...r.length>0?{notes:r}:{}}},uninstall(e){let t=x6(e);return t.kind==="failed"?{kind:"failed",reason:t.reason}:{kind:t.kind,configPath:t.plistPath}},status(e){let t=C6(e);return{name:t.name,label:t.label,installed:t.installed,configPath:t.plistPath,logFile:t.logFile,...t.pid!==void 0?{pid:t.pid}:{},...t.lastExitStatus!==void 0?{lastExitStatus:t.lastExitStatus}:{}}},restart(e){if(!this.isInstalled(e))return{kind:"not-installed",configPath:Or(e)};if(typeof process.getuid!="function")return{kind:"failed",reason:"process.getuid is unavailable \u2014 restart requires a POSIX system."};try{return zCe("launchctl",["kickstart","-k",`${sa()}/${zt(e)}`],{stdio:["ignore","pipe","pipe"],timeout:So}),{kind:"restarted",label:zt(e)}}catch(t){return{kind:"failed",reason:t.message}}},isInstalled(e){return JCe(Or(e))},configPath(e){return Or(e)},logPath(e){return Lc(e)},label(e){return zt(e)},readConfigFile(e){return A6(e)}};import{execFileSync as u_e}from"child_process";import{existsSync as U6}from"fs";G();import{homedir as JS}from"os";import{join as sm}from"path";function am(e=JS()){return sm(e,".config","systemd","user")}function Jt(e){return`afk-${e}.service`}function VS(e){return`afk-${e}.path`}function Q_(e){return`afk-${e}-restart.service`}function Zn(e,t=JS()){return sm(am(t),Jt(e))}function YS(e,t=JS()){return sm(am(t),VS(e))}function XS(e,t=JS()){return sm(am(t),Q_(e))}function lm(e){return Jt(e)}function Nc(e){return sm(To(),`service-${e}.log`)}var Bc=8e3;import{execFileSync as XCe}from"child_process";import{existsSync as Uc,mkdirSync as $6,readFileSync as QCe,renameSync as ZCe,rmSync as QS,unlinkSync as e_e,writeFileSync as t_e}from"fs";import{homedir as n_e}from"os";import{dirname as r_e}from"path";function I6(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/%/g,"%%")}function VCe(e){return`"${I6(e)}"`}function YCe(e){return I6(e)}function P6(e){let t=[];if(t.push("[Unit]"),t.push(`Description=${e.description}`),t.push("After=network-online.target"),t.push("Wants=network-online.target"),t.push(""),t.push("[Service]"),t.push("Type=simple"),t.push(`ExecStart=${e.execStart.map(VCe).join(" ")}`),t.push(`WorkingDirectory=${e.workingDirectory}`),t.push("Restart=always"),t.push("RestartSec=2"),t.push(`StandardOutput=append:${e.logFile}`),t.push(`StandardError=append:${e.logFile}`),e.environmentVariables&&Object.keys(e.environmentVariables).length>0)for(let n of Object.keys(e.environmentVariables).sort()){let r=e.environmentVariables[n]??"";t.push(`Environment="${n}=${YCe(r)}"`)}return t.push(""),t.push("[Install]"),t.push("WantedBy=default.target"),t.join(`
2058
2058
  `)+`
2059
- `}function M5(e){let t=[];t.push("[Unit]"),t.push(`Description=${e.description}`),t.push(""),t.push("[Path]");for(let n of e.pathModified)t.push(`PathModified=${n}`);return t.push(`Unit=${e.unit}`),t.push(""),t.push("[Install]"),t.push("WantedBy=default.target"),t.join(`
2059
+ `}function M6(e){let t=[];t.push("[Unit]"),t.push(`Description=${e.description}`),t.push(""),t.push("[Path]");for(let n of e.pathModified)t.push(`PathModified=${n}`);return t.push(`Unit=${e.unit}`),t.push(""),t.push("[Install]"),t.push("WantedBy=default.target"),t.join(`
2060
2060
  `)+`
2061
- `}function O5(e){let t=[];return t.push("[Unit]"),t.push(`Description=${e.description}`),t.push(""),t.push("[Service]"),t.push("Type=oneshot"),t.push(`ExecStart=${e.systemctlPath} --user restart ${e.targetUnit}`),t.join(`
2061
+ `}function O6(e){let t=[];return t.push("[Unit]"),t.push(`Description=${e.description}`),t.push(""),t.push("[Service]"),t.push("Type=oneshot"),t.push(`ExecStart=${e.systemctlPath} --user restart ${e.targetUnit}`),t.join(`
2062
2062
  `)+`
2063
- `}function jc(e){XCe("systemctl",["--user",...e],{stdio:["ignore","pipe","pipe"],timeout:Bc})}function o_e(e){let t=e.stderr;return(t?t.toString().trim():"")||e.message}var i_e=["/usr/bin/systemctl","/bin/systemctl"];function s_e(e=Uc){for(let t of i_e)if(e(t))return t;return"systemctl"}function Z_(e,t){let n=`${e}.tmp`;try{t_e(n,t,{encoding:"utf-8",flag:"wx",mode:384})}catch(r){return`Failed to write unit (tmp ${n}): ${r.message}`}try{ZCe(n,e)}catch(r){try{e_e(n)}catch{}return`Failed to install unit (rename ${n} \u2192 ${e}): ${r.message}`}}var D5="Always-on across logout/reboot needs lingering: run 'loginctl enable-linger' (or 'sudo loginctl enable-linger <user>').";function eI(e){for(let t of e)QS(t,{force:!0})}function F5(e,t={}){let n=Zn(e);if(Uc(n))return{kind:"already-installed",configPath:n,label:Jt(e)};let r;try{r=im(e,t._entrypointExistsCheck)}catch(d){return{kind:"failed",reason:d.message}}let o=t.noWatch?void 0:qS(e,t._entrypointExistsCheck),i=Nc(e);$5(am(),{recursive:!0}),$5(r_e(i),{recursive:!0});let s={PATH:GS(),...t.environment??{}},a=P5({description:`AFK ${e} service`,execStart:r,workingDirectory:n_e(),logFile:i,environmentVariables:s}),l=Z_(n,a);if(l)return{kind:"failed",reason:l};let c=[n],u=!1;if(o&&o.length>0){let d=s_e(),p=O5({description:`AFK ${e} rebuild restart`,systemctlPath:d,targetUnit:Jt(e)}),f=Z_(XS(e),p);if(f)return eI(c),{kind:"failed",reason:f};c.push(XS(e));let g=M5({description:`AFK ${e} rebuild watch`,pathModified:o,unit:Q_(e)}),h=Z_(YS(e),g);if(h)return eI(c),{kind:"failed",reason:h};c.push(YS(e)),u=!0}if(t.dryRun)return{kind:"installed",configPath:n,label:Jt(e),autoRestartOnRebuild:u,notes:["(dry-run) systemctl was skipped; service is NOT yet running.",`Load manually: systemctl --user daemon-reload && systemctl --user enable --now ${Jt(e)}`,D5]};try{jc(["daemon-reload"]),jc(["enable","--now",Jt(e)]),u&&jc(["enable","--now",VS(e)])}catch(d){return eI(c),{kind:"failed",reason:`systemctl enable failed: ${o_e(d)}`}}return{kind:"installed",configPath:n,label:Jt(e),autoRestartOnRebuild:u,notes:[D5]}}function L5(e){let t=Zn(e);if(!Uc(t))return{kind:"not-installed",configPath:t};let n=YS(e),r=Uc(n),o=XS(e),i=Uc(o);try{r&&jc(["disable","--now",VS(e)])}catch{}try{jc(["disable","--now",Jt(e)])}catch{}try{QS(t,{force:!0}),r&&QS(n,{force:!0}),i&&QS(o,{force:!0})}catch(s){return{kind:"failed",reason:`Failed to remove unit: ${s.message}`}}try{jc(["daemon-reload"])}catch{}return{kind:"uninstalled",configPath:t}}function N5(e){let t=Zn(e);if(Uc(t))return QCe(t,"utf-8")}import{execFileSync as a_e}from"child_process";import{existsSync as l_e}from"fs";function c_e(e){let t={};for(let n of e.split(`
2064
- `)){let r=n.indexOf("=");if(r<0)continue;let o=n.slice(0,r).trim(),i=n.slice(r+1).trim();switch(o){case"MainPID":{let s=Number.parseInt(i,10);Number.isFinite(s)&&s>0&&(t.pid=s);break}case"ExecMainStatus":{let s=Number.parseInt(i,10);Number.isFinite(s)&&(t.lastExitStatus=s);break}case"ActiveState":i&&(t.activeState=i);break;case"LoadState":i&&(t.loadState=i);break;default:break}}return t}function B5(e){let t=Zn(e),n={name:e,label:lm(e),installed:l_e(t),configPath:t,logFile:Nc(e)};if(!n.installed)return n;try{let r=a_e("systemctl",["--user","show",Jt(e),"--property=MainPID,ExecMainStatus,ActiveState,LoadState"],{encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:Bc}),o=c_e(r);o.pid!==void 0&&(n.pid=o.pid),o.lastExitStatus!==void 0&&(n.lastExitStatus=o.lastExitStatus)}catch{}return n}var j5={backend:"systemd",configKind:"systemd user unit",install(e,t={}){return F5(e,t)},uninstall(e){return L5(e)},status(e){return B5(e)},restart(e){if(!U5(Zn(e)))return{kind:"not-installed",configPath:Zn(e)};try{return u_e("systemctl",["--user","restart",Jt(e)],{stdio:["ignore","pipe","pipe"],timeout:Bc}),{kind:"restarted",label:lm(e)}}catch(t){let n=t.stderr;return{kind:"failed",reason:n&&n.toString().trim()||t.message}}},isInstalled(e){return U5(Zn(e))},configPath(e){return Zn(e)},logPath(e){return Nc(e)},label(e){return lm(e)},readConfigFile(e){return N5(e)}};var Hc=["telegram","daemon"];function H5(e=process.platform){switch(e){case"darwin":return _5;case"linux":return j5;default:return null}}var W5="macOS (launchd) and Linux (systemd --user)";function cm(){let e=H5();if(!e)throw new Error(`'afk service' is not supported on ${process.platform}. Supported: ${W5}.`);return e}function ZS(e){let t=e.toLowerCase();if(Hc.includes(t))return t;throw new Error(`Unknown service '${e}'. Supported: ${Hc.join(", ")}.`)}function G5(e){let t=e.command("service").description("Manage AFK background services (launchd on macOS, systemd --user on Linux) \u2014 always-on, auto-restart");t.command("install <name>").description(`Install <${Hc.join("|")}> as an OS service that starts on login and relaunches on crash`).option("--no-watch","Disable auto-restart-on-rebuild (launchd WatchPaths / systemd .path unit)").option("--dry-run","Write the config file but do not register with the supervisor",!1).action((n,r)=>{try{let o=cm(),i=ZS(n),s=o.install(i,{noWatch:r.watch===!1,dryRun:!!r.dryRun});s.kind==="already-installed"&&(console.log(m.warning(`\u26A0 ${s.label} already installed at ${s.configPath}`)),console.log(m.meta(` Run 'afk service uninstall ${i}' first to reinstall.`)),process.exit(1)),s.kind==="failed"&&(console.error(m.error(`\u2717 Install failed: ${s.reason}`)),process.exit(1)),console.log(m.success(`\u2713 Installed ${s.label}`)),console.log(m.meta(` Config: ${s.configPath} (${o.configKind})`)),console.log(m.meta(` Log: ${o.logPath(i)}`)),s.autoRestartOnRebuild?console.log(m.meta(" Auto-restart on rebuild: on")):console.log(m.meta(` Auto-restart on rebuild: off \u2014 run 'afk service restart ${i}' after updates.`));for(let a of s.notes??[])console.log(m.info(` ${a}`));r.dryRun||console.log(m.meta(` Status: afk service status ${i}`))}catch(o){J(o)}}),t.command("uninstall <name>").description("Stop the service and remove its config (LaunchAgent plist / systemd unit)").action(n=>{try{let r=cm(),o=ZS(n),i=r.uninstall(o);if(i.kind==="not-installed"){console.log(m.warning(`\u26A0 ${r.label(o)} is not installed (no config at ${i.configPath})`));return}i.kind==="failed"&&(console.error(m.error(`\u2717 Uninstall failed: ${i.reason}`)),process.exit(1)),console.log(m.success(`\u2713 Uninstalled ${r.label(o)}`)),console.log(m.meta(` Removed: ${i.configPath}`))}catch(r){J(r)}}),t.command("status [name]").description("Show running PID, last exit status, and log file for one or all services").action(n=>{try{let r=cm();if(n){K5(r.status(ZS(n)),r.configKind);return}for(let o of Hc)K5(r.status(o),r.configKind),console.log("")}catch(r){J(r)}}),t.command("list").description("List recognised service names and whether each is installed").action(()=>{try{let n=cm();console.log(m.heading(`AFK services (${n.backend}):`));for(let r of Hc){let o=n.isInstalled(r),i=o?m.success("\u25CF"):m.dim("\u25CB"),s=o?m.meta("installed"):m.meta("not installed");console.log(` ${i} ${r.padEnd(10)} ${s} ${m.meta(n.configPath(r))}`)}}catch(n){J(n)}}),t.command("restart <name>").description("Restart the service (launchctl kickstart -k / systemctl --user restart)").action(n=>{try{let r=cm(),o=ZS(n),i=r.restart(o);i.kind==="not-installed"&&(console.error(m.error(`\u2717 ${r.label(o)} is not installed. Run 'afk service install ${o}' first.`)),process.exit(1)),i.kind==="failed"&&(console.error(m.error(`\u2717 Restart failed: ${i.reason}`)),process.exit(1)),console.log(m.success(`\u2713 Restarted ${i.label}`))}catch(r){J(r)}})}function K5(e,t){if(console.log(m.heading(`${e.label}`)),!e.installed){console.log(` ${m.dim("\u25CB")} Not installed`),console.log(m.meta(` Config: ${e.configPath} (${t})`)),console.log(m.meta(` Install: afk service install ${e.name}`));return}e.pid!==void 0?console.log(` ${m.success("\u25CF")} Running (PID ${e.pid})`):(console.log(` ${m.warning("\u25CF")} Installed but not running`),e.lastExitStatus!==void 0&&e.lastExitStatus!==0&&console.log(m.meta(` Last exit status: ${e.lastExitStatus}`))),console.log(m.meta(` Config: ${e.configPath} (${t})`)),console.log(m.meta(` Log: ${e.logFile}`))}import{execFileSync as d_e}from"child_process";import{chmodSync as p_e,existsSync as um,mkdirSync as J5,readdirSync as m_e,readFileSync as f_e,renameSync as V5,writeFileSync as Y5}from"fs";import{basename as g_e,dirname as nI,join as rI}from"path";import{randomBytes as X5}from"crypto";import{createInterface as h_e}from"node:readline";mg();G();function y_e(e){let t=h_e({input:process.stdin,output:process.stdout});return new Promise(n=>{t.question(e,()=>{t.close(),n()})})}var Ci="chrome-devtools",tI=["stable","beta","canary","dev"];function b_e(e="stable"){let t=["chrome-devtools-mcp@latest","--autoConnect"];return e!=="stable"&&t.push("--channel",e),{command:"npx",args:t}}function q5(e){if(!um(e))return{mcpServers:{}};let t;try{t=f_e(e,"utf-8")}catch(o){throw new Error(`Failed to read MCP config at ${e}: ${o.message}`)}let n;try{n=JSON.parse(t)}catch{throw new Error(`MCP config at ${e} is not valid JSON. Fix or remove it, then retry.`)}if(typeof n!="object"||n===null||Array.isArray(n))throw new Error(`MCP config at ${e} must be a JSON object.`);let r=n;if(Array.isArray(r.mcpServers))throw new Error(`MCP config at ${e} has an invalid "mcpServers" (must be a JSON object, not an array).`);return(r.mcpServers===void 0||typeof r.mcpServers!="object"||r.mcpServers===null)&&(r.mcpServers={}),r}function z5(e,t){J5(nI(e),{recursive:!0});let n=rI(nI(e),`.mcp.json.${process.pid}.${X5(4).toString("hex")}.tmp`);Y5(n,`${JSON.stringify(t,null,2)}
2065
- `,"utf-8"),V5(n,e)}function w_e(){let e=process.platform==="darwin"?["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome","/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta","/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary"]:["google-chrome","google-chrome-stable","chromium","chromium-browser"];for(let t of e)try{let r=d_e(t,["--version"],{encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:5e3}).match(/(\d+)\.\d+\.\d+/);if(r!==null&&r[1]!==void 0)return parseInt(r[1],10)}catch{}return null}function S_e(){let e=w_e();console.log(""),console.log(m.heading("Drive your real Chrome \u2014 one-time setup:")),e===null?console.log(m.meta(" \u2022 Chrome not detected. autoConnect requires Chrome \u2265 144.")):e<144?console.log(m.warning(` \u2022 Detected Chrome ${e} \u2014 autoConnect requires \u2265 144. Please update Chrome.`)):console.log(m.meta(` \u2022 Detected Chrome ${e} \u2713 (autoConnect needs \u2265 144)`)),console.log(m.meta(" 1. In Chrome, open chrome://inspect/#remote-debugging and enable it (one time).")),console.log(m.meta(' 2. The first time the agent drives Chrome, click "Allow" on the prompt.')),console.log(m.meta(' 3. Chrome shows a "being controlled by automated test software" banner while active.')),console.log(""),console.log(m.meta("The agent gains mcp__chrome-devtools__* tools (navigate, click, fill, take_snapshot, \u2026)")),console.log(m.meta("driving your REAL, logged-in profile. Run `/mcp` in the REPL to confirm it connected.")),console.log(m.meta("Undo anytime with `afk browser disconnect`."))}function Q5(e){let t=e.command("browser").description("Give the agent web hands: connect your real Chrome, or save a login it reuses");t.command("connect").description("Wire chrome-devtools-mcp (--autoConnect) so the agent can drive your real, logged-in Chrome").option("--channel <channel>",`Chrome channel autoConnect targets (${tI.join("|")})`,"stable").action(n=>{try{let r=(n.channel??"stable").toLowerCase();if(!tI.includes(r))throw new Error(`--channel must be one of ${tI.join(", ")} (got "${n.channel}")`);let o=Os(),i=q5(o);i.mcpServers===void 0&&(i.mcpServers={});let s=b_e(r),a=i.mcpServers[Ci];if(a!==void 0&&JSON.stringify(a)===JSON.stringify(s))console.log(m.success(`\u2713 "${Ci}" already configured`)),console.log(m.meta(` Config: ${o}`));else{i.mcpServers[Ci]=s,z5(o,i);let l=a===void 0?"Added":"Updated";console.log(m.success(`\u2713 ${l} "${Ci}" MCP server`)),console.log(m.meta(` Config: ${o}`)),console.log(m.meta(` Runs: npx ${s.args?.join(" ")??""}`))}S_e()}catch(r){J(r)}}),t.command("disconnect").description("Remove the chrome-devtools server from your MCP config").action(()=>{try{let n=Os();if(!um(n)){console.log(m.warning(`\u26A0 No MCP config at ${n} \u2014 nothing to remove.`));return}let r=q5(n);if(r.mcpServers===void 0||r.mcpServers[Ci]===void 0){console.log(m.warning(`\u26A0 "${Ci}" is not configured \u2014 nothing to remove.`));return}delete r.mcpServers[Ci],z5(n,r),console.log(m.success(`\u2713 Removed "${Ci}" from ${n}`))}catch(n){J(n)}}),t.command("login <url>").description("Open a headed browser, log in manually, and save the session to a vault profile the agent's native browser tools reuse").option("--profile <name>","Vault profile name to save the session under","default").action(async(n,r)=>{try{let o=(r.profile??"default").trim();au(o);let i;try{i=new URL(n)}catch{throw new Error(`Invalid URL: ${n}`)}if(i.protocol!=="http:"&&i.protocol!=="https:")throw new Error(`login URL must be http(s), got: ${i.protocol}`);let s=lu(o),{chromium:a}=await import("playwright");console.log(m.meta(`Launching a browser for profile "${o}"\u2026`));let l=await a.launch({headless:!1}).catch(f=>{throw td(f,!1)}),c=await l.newContext(um(s)?{storageState:s}:{});await(await c.newPage()).goto(n,{waitUntil:"load"}).catch(()=>{}),console.log(""),console.log(m.heading("Log in to the site in the opened browser window.")),console.log(m.meta("When fully logged in, return here and press Enter to save the session.")),console.log(m.meta("(Do NOT close the browser window yourself \u2014 this command closes it for you.)")),await y_e("Press Enter to save the session\u2026 ");let d=await c.storageState();J5(Fv(o),{recursive:!0});let p=rI(nI(s),`.${g_e(s)}.${process.pid}.${X5(4).toString("hex")}.tmp`);Y5(p,JSON.stringify(d),{mode:384}),p_e(p,384),V5(p,s),await l.close().catch(()=>{}),console.log(m.success(`\u2713 Saved session for profile "${o}"`)),console.log(m.meta(` Vault: ${s} (0600 \u2014 treat as a credential)`)),console.log(m.meta(" Point the agent at it:")),console.log(m.meta(` export AFK_BROWSER_DEFAULT_PROFILE=${o}`))}catch(o){J(o)}}),t.command("profiles").description("List saved browser session-vault profiles").action(()=>{try{let n=Dv(),r=um(n)?m_e(n,{withFileTypes:!0}).filter(o=>o.isDirectory()):[];if(r.length===0){console.log(m.meta("No saved profiles. Create one with `afk browser login <url> --profile <name>`."));return}console.log(m.heading("Saved browser profiles:"));for(let o of r){let i=um(rI(n,o.name,"storageState.json")),s=i?m.success("\u25CF"):m.meta("\u25CB"),a=i?"":m.meta(" (no saved session)");console.log(` ${s} ${o.name}${a}`)}console.log(""),console.log(m.meta("Use one: export AFK_BROWSER_DEFAULT_PROFILE=<name>"))}catch(n){J(n)}})}import{readFileSync as v_e,readdirSync as k_e,statSync as T_e}from"fs";import{join as aI}from"path";G();import{join as ot}from"path";function ev(){return ot(Tt(),"improve")}function _i(){return ot(ev(),"failure-cards")}function Z5(){return ot(_i(),".index.jsonl")}function dm(e){return ot(_i(),`${e}.json`)}function tv(e){return ot(_i(),`${e}.md`)}function e6(){return ot(fe(),"witness")}function aa(){return ot(ev(),"proposals")}function t6(){return ot(aa(),".index.jsonl")}function oI(e){return ot(aa(),`${e}.json`)}function n6(e){return ot(aa(),`${e}.md`)}function Ii(){return ot(ev(),"eval-cases")}function r6(){return ot(Ii(),".index.jsonl")}function iI(e){return ot(Ii(),`${e}.json`)}function sI(e){return ot(Ii(),`${e}.fixture.jsonl`)}function o6(e){return ot(Ii(),`${e}.md`)}function Wc(){return ot(ev(),"eval-runs")}function i6(){return ot(Wc(),".index.jsonl")}function s6(e){return ot(Wc(),`${e}.json`)}function a6(e){return ot(Wc(),`${e}.md`)}W();function l6(e){let t=e.trim(),n=/^(\d+)\s*([smhd])$/i.exec(t);if(!n)return;let r=Number.parseInt(n[1]??"0",10),o=(n[2]??"").toLowerCase();if(!(!Number.isFinite(r)||r<=0))switch(o){case"s":return r*1e3;case"m":return r*60*1e3;case"h":return r*60*60*1e3;case"d":return r*24*60*60*1e3;default:return}}function c6(e={}){let t=e.witnessRoot??e6(),n=e.afkHome??T.AFK_HOME??E_e(),r=e.sinceMs,o={sessionsScanned:0,sessionsSkippedOld:0,sessionsSkippedEmpty:0,invalidLineCount:0,sessions:[]},i;try{i=k_e(t)}catch{return o}for(let s of i){if(s.startsWith("."))continue;let a=aI(t,s),l;try{l=T_e(a)}catch{continue}if(!l.isDirectory())continue;if(r!==void 0&&l.mtimeMs<r){o.sessionsSkippedOld+=1;continue}let c=aI(a,"trace.jsonl"),u;try{u=v_e(c,"utf-8")}catch{o.sessionsSkippedEmpty+=1;continue}let d=R_e(c,n),p=Kc({sessionId:s,tracePath:c,relativeTracePath:d,content:u,sessionMtimeMs:l.mtimeMs});o.sessions.push(p),o.sessionsScanned+=1,o.invalidLineCount+=p.invalidLineCount}return o}function Kc(e){let{sessionId:t,tracePath:n,relativeTracePath:r,content:o,sessionMtimeMs:i}=e,s=[],a=0,l=o.split(`
2063
+ `}function jc(e){XCe("systemctl",["--user",...e],{stdio:["ignore","pipe","pipe"],timeout:Bc})}function o_e(e){let t=e.stderr;return(t?t.toString().trim():"")||e.message}var i_e=["/usr/bin/systemctl","/bin/systemctl"];function s_e(e=Uc){for(let t of i_e)if(e(t))return t;return"systemctl"}function Z_(e,t){let n=`${e}.tmp`;try{t_e(n,t,{encoding:"utf-8",flag:"wx",mode:384})}catch(r){return`Failed to write unit (tmp ${n}): ${r.message}`}try{ZCe(n,e)}catch(r){try{e_e(n)}catch{}return`Failed to install unit (rename ${n} \u2192 ${e}): ${r.message}`}}var D6="Always-on across logout/reboot needs lingering: run 'loginctl enable-linger' (or 'sudo loginctl enable-linger <user>').";function eI(e){for(let t of e)QS(t,{force:!0})}function F6(e,t={}){let n=Zn(e);if(Uc(n))return{kind:"already-installed",configPath:n,label:Jt(e)};let r;try{r=im(e,t._entrypointExistsCheck)}catch(d){return{kind:"failed",reason:d.message}}let o=t.noWatch?void 0:qS(e,t._entrypointExistsCheck),i=Nc(e);$6(am(),{recursive:!0}),$6(r_e(i),{recursive:!0});let s={PATH:GS(),...t.environment??{}},a=P6({description:`AFK ${e} service`,execStart:r,workingDirectory:n_e(),logFile:i,environmentVariables:s}),l=Z_(n,a);if(l)return{kind:"failed",reason:l};let c=[n],u=!1;if(o&&o.length>0){let d=s_e(),p=O6({description:`AFK ${e} rebuild restart`,systemctlPath:d,targetUnit:Jt(e)}),f=Z_(XS(e),p);if(f)return eI(c),{kind:"failed",reason:f};c.push(XS(e));let g=M6({description:`AFK ${e} rebuild watch`,pathModified:o,unit:Q_(e)}),h=Z_(YS(e),g);if(h)return eI(c),{kind:"failed",reason:h};c.push(YS(e)),u=!0}if(t.dryRun)return{kind:"installed",configPath:n,label:Jt(e),autoRestartOnRebuild:u,notes:["(dry-run) systemctl was skipped; service is NOT yet running.",`Load manually: systemctl --user daemon-reload && systemctl --user enable --now ${Jt(e)}`,D6]};try{jc(["daemon-reload"]),jc(["enable","--now",Jt(e)]),u&&jc(["enable","--now",VS(e)])}catch(d){return eI(c),{kind:"failed",reason:`systemctl enable failed: ${o_e(d)}`}}return{kind:"installed",configPath:n,label:Jt(e),autoRestartOnRebuild:u,notes:[D6]}}function L6(e){let t=Zn(e);if(!Uc(t))return{kind:"not-installed",configPath:t};let n=YS(e),r=Uc(n),o=XS(e),i=Uc(o);try{r&&jc(["disable","--now",VS(e)])}catch{}try{jc(["disable","--now",Jt(e)])}catch{}try{QS(t,{force:!0}),r&&QS(n,{force:!0}),i&&QS(o,{force:!0})}catch(s){return{kind:"failed",reason:`Failed to remove unit: ${s.message}`}}try{jc(["daemon-reload"])}catch{}return{kind:"uninstalled",configPath:t}}function N6(e){let t=Zn(e);if(Uc(t))return QCe(t,"utf-8")}import{execFileSync as a_e}from"child_process";import{existsSync as l_e}from"fs";function c_e(e){let t={};for(let n of e.split(`
2064
+ `)){let r=n.indexOf("=");if(r<0)continue;let o=n.slice(0,r).trim(),i=n.slice(r+1).trim();switch(o){case"MainPID":{let s=Number.parseInt(i,10);Number.isFinite(s)&&s>0&&(t.pid=s);break}case"ExecMainStatus":{let s=Number.parseInt(i,10);Number.isFinite(s)&&(t.lastExitStatus=s);break}case"ActiveState":i&&(t.activeState=i);break;case"LoadState":i&&(t.loadState=i);break;default:break}}return t}function B6(e){let t=Zn(e),n={name:e,label:lm(e),installed:l_e(t),configPath:t,logFile:Nc(e)};if(!n.installed)return n;try{let r=a_e("systemctl",["--user","show",Jt(e),"--property=MainPID,ExecMainStatus,ActiveState,LoadState"],{encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:Bc}),o=c_e(r);o.pid!==void 0&&(n.pid=o.pid),o.lastExitStatus!==void 0&&(n.lastExitStatus=o.lastExitStatus)}catch{}return n}var j6={backend:"systemd",configKind:"systemd user unit",install(e,t={}){return F6(e,t)},uninstall(e){return L6(e)},status(e){return B6(e)},restart(e){if(!U6(Zn(e)))return{kind:"not-installed",configPath:Zn(e)};try{return u_e("systemctl",["--user","restart",Jt(e)],{stdio:["ignore","pipe","pipe"],timeout:Bc}),{kind:"restarted",label:lm(e)}}catch(t){let n=t.stderr;return{kind:"failed",reason:n&&n.toString().trim()||t.message}}},isInstalled(e){return U6(Zn(e))},configPath(e){return Zn(e)},logPath(e){return Nc(e)},label(e){return lm(e)},readConfigFile(e){return N6(e)}};var Hc=["telegram","daemon"];function H6(e=process.platform){switch(e){case"darwin":return _6;case"linux":return j6;default:return null}}var W6="macOS (launchd) and Linux (systemd --user)";function cm(){let e=H6();if(!e)throw new Error(`'afk service' is not supported on ${process.platform}. Supported: ${W6}.`);return e}function ZS(e){let t=e.toLowerCase();if(Hc.includes(t))return t;throw new Error(`Unknown service '${e}'. Supported: ${Hc.join(", ")}.`)}function G6(e){let t=e.command("service").description("Manage AFK background services (launchd on macOS, systemd --user on Linux) \u2014 always-on, auto-restart");t.command("install <name>").description(`Install <${Hc.join("|")}> as an OS service that starts on login and relaunches on crash`).option("--no-watch","Disable auto-restart-on-rebuild (launchd WatchPaths / systemd .path unit)").option("--dry-run","Write the config file but do not register with the supervisor",!1).action((n,r)=>{try{let o=cm(),i=ZS(n),s=o.install(i,{noWatch:r.watch===!1,dryRun:!!r.dryRun});s.kind==="already-installed"&&(console.log(m.warning(`\u26A0 ${s.label} already installed at ${s.configPath}`)),console.log(m.meta(` Run 'afk service uninstall ${i}' first to reinstall.`)),process.exit(1)),s.kind==="failed"&&(console.error(m.error(`\u2717 Install failed: ${s.reason}`)),process.exit(1)),console.log(m.success(`\u2713 Installed ${s.label}`)),console.log(m.meta(` Config: ${s.configPath} (${o.configKind})`)),console.log(m.meta(` Log: ${o.logPath(i)}`)),s.autoRestartOnRebuild?console.log(m.meta(" Auto-restart on rebuild: on")):console.log(m.meta(` Auto-restart on rebuild: off \u2014 run 'afk service restart ${i}' after updates.`));for(let a of s.notes??[])console.log(m.info(` ${a}`));r.dryRun||console.log(m.meta(` Status: afk service status ${i}`))}catch(o){J(o)}}),t.command("uninstall <name>").description("Stop the service and remove its config (LaunchAgent plist / systemd unit)").action(n=>{try{let r=cm(),o=ZS(n),i=r.uninstall(o);if(i.kind==="not-installed"){console.log(m.warning(`\u26A0 ${r.label(o)} is not installed (no config at ${i.configPath})`));return}i.kind==="failed"&&(console.error(m.error(`\u2717 Uninstall failed: ${i.reason}`)),process.exit(1)),console.log(m.success(`\u2713 Uninstalled ${r.label(o)}`)),console.log(m.meta(` Removed: ${i.configPath}`))}catch(r){J(r)}}),t.command("status [name]").description("Show running PID, last exit status, and log file for one or all services").action(n=>{try{let r=cm();if(n){K6(r.status(ZS(n)),r.configKind);return}for(let o of Hc)K6(r.status(o),r.configKind),console.log("")}catch(r){J(r)}}),t.command("list").description("List recognised service names and whether each is installed").action(()=>{try{let n=cm();console.log(m.heading(`AFK services (${n.backend}):`));for(let r of Hc){let o=n.isInstalled(r),i=o?m.success("\u25CF"):m.dim("\u25CB"),s=o?m.meta("installed"):m.meta("not installed");console.log(` ${i} ${r.padEnd(10)} ${s} ${m.meta(n.configPath(r))}`)}}catch(n){J(n)}}),t.command("restart <name>").description("Restart the service (launchctl kickstart -k / systemctl --user restart)").action(n=>{try{let r=cm(),o=ZS(n),i=r.restart(o);i.kind==="not-installed"&&(console.error(m.error(`\u2717 ${r.label(o)} is not installed. Run 'afk service install ${o}' first.`)),process.exit(1)),i.kind==="failed"&&(console.error(m.error(`\u2717 Restart failed: ${i.reason}`)),process.exit(1)),console.log(m.success(`\u2713 Restarted ${i.label}`))}catch(r){J(r)}})}function K6(e,t){if(console.log(m.heading(`${e.label}`)),!e.installed){console.log(` ${m.dim("\u25CB")} Not installed`),console.log(m.meta(` Config: ${e.configPath} (${t})`)),console.log(m.meta(` Install: afk service install ${e.name}`));return}e.pid!==void 0?console.log(` ${m.success("\u25CF")} Running (PID ${e.pid})`):(console.log(` ${m.warning("\u25CF")} Installed but not running`),e.lastExitStatus!==void 0&&e.lastExitStatus!==0&&console.log(m.meta(` Last exit status: ${e.lastExitStatus}`))),console.log(m.meta(` Config: ${e.configPath} (${t})`)),console.log(m.meta(` Log: ${e.logFile}`))}import{execFileSync as d_e}from"child_process";import{chmodSync as p_e,existsSync as um,mkdirSync as J6,readdirSync as m_e,readFileSync as f_e,renameSync as V6,writeFileSync as Y6}from"fs";import{basename as g_e,dirname as nI,join as rI}from"path";import{randomBytes as X6}from"crypto";import{createInterface as h_e}from"node:readline";mg();G();function y_e(e){let t=h_e({input:process.stdin,output:process.stdout});return new Promise(n=>{t.question(e,()=>{t.close(),n()})})}var Ci="chrome-devtools",tI=["stable","beta","canary","dev"];function b_e(e="stable"){let t=["chrome-devtools-mcp@latest","--autoConnect"];return e!=="stable"&&t.push("--channel",e),{command:"npx",args:t}}function q6(e){if(!um(e))return{mcpServers:{}};let t;try{t=f_e(e,"utf-8")}catch(o){throw new Error(`Failed to read MCP config at ${e}: ${o.message}`)}let n;try{n=JSON.parse(t)}catch{throw new Error(`MCP config at ${e} is not valid JSON. Fix or remove it, then retry.`)}if(typeof n!="object"||n===null||Array.isArray(n))throw new Error(`MCP config at ${e} must be a JSON object.`);let r=n;if(Array.isArray(r.mcpServers))throw new Error(`MCP config at ${e} has an invalid "mcpServers" (must be a JSON object, not an array).`);return(r.mcpServers===void 0||typeof r.mcpServers!="object"||r.mcpServers===null)&&(r.mcpServers={}),r}function z6(e,t){J6(nI(e),{recursive:!0});let n=rI(nI(e),`.mcp.json.${process.pid}.${X6(4).toString("hex")}.tmp`);Y6(n,`${JSON.stringify(t,null,2)}
2065
+ `,"utf-8"),V6(n,e)}function w_e(){let e=process.platform==="darwin"?["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome","/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta","/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary"]:["google-chrome","google-chrome-stable","chromium","chromium-browser"];for(let t of e)try{let r=d_e(t,["--version"],{encoding:"utf-8",stdio:["ignore","pipe","ignore"],timeout:5e3}).match(/(\d+)\.\d+\.\d+/);if(r!==null&&r[1]!==void 0)return parseInt(r[1],10)}catch{}return null}function S_e(){let e=w_e();console.log(""),console.log(m.heading("Drive your real Chrome \u2014 one-time setup:")),e===null?console.log(m.meta(" \u2022 Chrome not detected. autoConnect requires Chrome \u2265 144.")):e<144?console.log(m.warning(` \u2022 Detected Chrome ${e} \u2014 autoConnect requires \u2265 144. Please update Chrome.`)):console.log(m.meta(` \u2022 Detected Chrome ${e} \u2713 (autoConnect needs \u2265 144)`)),console.log(m.meta(" 1. In Chrome, open chrome://inspect/#remote-debugging and enable it (one time).")),console.log(m.meta(' 2. The first time the agent drives Chrome, click "Allow" on the prompt.')),console.log(m.meta(' 3. Chrome shows a "being controlled by automated test software" banner while active.')),console.log(""),console.log(m.meta("The agent gains mcp__chrome-devtools__* tools (navigate, click, fill, take_snapshot, \u2026)")),console.log(m.meta("driving your REAL, logged-in profile. Run `/mcp` in the REPL to confirm it connected.")),console.log(m.meta("Undo anytime with `afk browser disconnect`."))}function Q6(e){let t=e.command("browser").description("Give the agent web hands: connect your real Chrome, or save a login it reuses");t.command("connect").description("Wire chrome-devtools-mcp (--autoConnect) so the agent can drive your real, logged-in Chrome").option("--channel <channel>",`Chrome channel autoConnect targets (${tI.join("|")})`,"stable").action(n=>{try{let r=(n.channel??"stable").toLowerCase();if(!tI.includes(r))throw new Error(`--channel must be one of ${tI.join(", ")} (got "${n.channel}")`);let o=Os(),i=q6(o);i.mcpServers===void 0&&(i.mcpServers={});let s=b_e(r),a=i.mcpServers[Ci];if(a!==void 0&&JSON.stringify(a)===JSON.stringify(s))console.log(m.success(`\u2713 "${Ci}" already configured`)),console.log(m.meta(` Config: ${o}`));else{i.mcpServers[Ci]=s,z6(o,i);let l=a===void 0?"Added":"Updated";console.log(m.success(`\u2713 ${l} "${Ci}" MCP server`)),console.log(m.meta(` Config: ${o}`)),console.log(m.meta(` Runs: npx ${s.args?.join(" ")??""}`))}S_e()}catch(r){J(r)}}),t.command("disconnect").description("Remove the chrome-devtools server from your MCP config").action(()=>{try{let n=Os();if(!um(n)){console.log(m.warning(`\u26A0 No MCP config at ${n} \u2014 nothing to remove.`));return}let r=q6(n);if(r.mcpServers===void 0||r.mcpServers[Ci]===void 0){console.log(m.warning(`\u26A0 "${Ci}" is not configured \u2014 nothing to remove.`));return}delete r.mcpServers[Ci],z6(n,r),console.log(m.success(`\u2713 Removed "${Ci}" from ${n}`))}catch(n){J(n)}}),t.command("login <url>").description("Open a headed browser, log in manually, and save the session to a vault profile the agent's native browser tools reuse").option("--profile <name>","Vault profile name to save the session under","default").action(async(n,r)=>{try{let o=(r.profile??"default").trim();au(o);let i;try{i=new URL(n)}catch{throw new Error(`Invalid URL: ${n}`)}if(i.protocol!=="http:"&&i.protocol!=="https:")throw new Error(`login URL must be http(s), got: ${i.protocol}`);let s=lu(o),{chromium:a}=await import("playwright");console.log(m.meta(`Launching a browser for profile "${o}"\u2026`));let l=await a.launch({headless:!1}).catch(f=>{throw td(f,!1)}),c=await l.newContext(um(s)?{storageState:s}:{});await(await c.newPage()).goto(n,{waitUntil:"load"}).catch(()=>{}),console.log(""),console.log(m.heading("Log in to the site in the opened browser window.")),console.log(m.meta("When fully logged in, return here and press Enter to save the session.")),console.log(m.meta("(Do NOT close the browser window yourself \u2014 this command closes it for you.)")),await y_e("Press Enter to save the session\u2026 ");let d=await c.storageState();J6(Fv(o),{recursive:!0});let p=rI(nI(s),`.${g_e(s)}.${process.pid}.${X6(4).toString("hex")}.tmp`);Y6(p,JSON.stringify(d),{mode:384}),p_e(p,384),V6(p,s),await l.close().catch(()=>{}),console.log(m.success(`\u2713 Saved session for profile "${o}"`)),console.log(m.meta(` Vault: ${s} (0600 \u2014 treat as a credential)`)),console.log(m.meta(" Point the agent at it:")),console.log(m.meta(` export AFK_BROWSER_DEFAULT_PROFILE=${o}`))}catch(o){J(o)}}),t.command("profiles").description("List saved browser session-vault profiles").action(()=>{try{let n=Dv(),r=um(n)?m_e(n,{withFileTypes:!0}).filter(o=>o.isDirectory()):[];if(r.length===0){console.log(m.meta("No saved profiles. Create one with `afk browser login <url> --profile <name>`."));return}console.log(m.heading("Saved browser profiles:"));for(let o of r){let i=um(rI(n,o.name,"storageState.json")),s=i?m.success("\u25CF"):m.meta("\u25CB"),a=i?"":m.meta(" (no saved session)");console.log(` ${s} ${o.name}${a}`)}console.log(""),console.log(m.meta("Use one: export AFK_BROWSER_DEFAULT_PROFILE=<name>"))}catch(n){J(n)}})}import{readFileSync as v_e,readdirSync as k_e,statSync as T_e}from"fs";import{join as aI}from"path";G();import{join as ot}from"path";function ev(){return ot(Tt(),"improve")}function _i(){return ot(ev(),"failure-cards")}function Z6(){return ot(_i(),".index.jsonl")}function dm(e){return ot(_i(),`${e}.json`)}function tv(e){return ot(_i(),`${e}.md`)}function e5(){return ot(fe(),"witness")}function aa(){return ot(ev(),"proposals")}function t5(){return ot(aa(),".index.jsonl")}function oI(e){return ot(aa(),`${e}.json`)}function n5(e){return ot(aa(),`${e}.md`)}function Ii(){return ot(ev(),"eval-cases")}function r5(){return ot(Ii(),".index.jsonl")}function iI(e){return ot(Ii(),`${e}.json`)}function sI(e){return ot(Ii(),`${e}.fixture.jsonl`)}function o5(e){return ot(Ii(),`${e}.md`)}function Wc(){return ot(ev(),"eval-runs")}function i5(){return ot(Wc(),".index.jsonl")}function s5(e){return ot(Wc(),`${e}.json`)}function a5(e){return ot(Wc(),`${e}.md`)}W();function l5(e){let t=e.trim(),n=/^(\d+)\s*([smhd])$/i.exec(t);if(!n)return;let r=Number.parseInt(n[1]??"0",10),o=(n[2]??"").toLowerCase();if(!(!Number.isFinite(r)||r<=0))switch(o){case"s":return r*1e3;case"m":return r*60*1e3;case"h":return r*60*60*1e3;case"d":return r*24*60*60*1e3;default:return}}function c5(e={}){let t=e.witnessRoot??e5(),n=e.afkHome??T.AFK_HOME??E_e(),r=e.sinceMs,o={sessionsScanned:0,sessionsSkippedOld:0,sessionsSkippedEmpty:0,invalidLineCount:0,sessions:[]},i;try{i=k_e(t)}catch{return o}for(let s of i){if(s.startsWith("."))continue;let a=aI(t,s),l;try{l=T_e(a)}catch{continue}if(!l.isDirectory())continue;if(r!==void 0&&l.mtimeMs<r){o.sessionsSkippedOld+=1;continue}let c=aI(a,"trace.jsonl"),u;try{u=v_e(c,"utf-8")}catch{o.sessionsSkippedEmpty+=1;continue}let d=R_e(c,n),p=Kc({sessionId:s,tracePath:c,relativeTracePath:d,content:u,sessionMtimeMs:l.mtimeMs});o.sessions.push(p),o.sessionsScanned+=1,o.invalidLineCount+=p.invalidLineCount}return o}function Kc(e){let{sessionId:t,tracePath:n,relativeTracePath:r,content:o,sessionMtimeMs:i}=e,s=[],a=0,l=o.split(`
2066
2066
  `);for(let c=0;c<l.length;c+=1){let u=l[c]??"";if(u.trim()==="")continue;let d;try{d=JSON.parse(u)}catch{a+=1;continue}let p=ub.safeParse(d);if(!p.success){a+=1;continue}s.push({sessionId:t,tracePath:n,relativeTracePath:r,lineNumber:c+1,rawLine:u,event:p.data})}return{sessionId:t,tracePath:n,relativeTracePath:r,sessionMtimeMs:i,events:s,invalidLineCount:a}}function E_e(){let e=T.AFK_HOME;return e&&e.length>0?e:aI(T.HOME??"",".afk")}function R_e(e,t){if(!t)return e;if(e.startsWith(t)){let n=e.slice(t.length);return n.startsWith("/")&&(n=n.slice(1)),n}return e}import{createHash as x_e}from"crypto";var vo=4,A_e=8,C_e="v1-bytes-tuple";function nv(e,t={}){let n=t.minRepeats??vo;if(n<2)throw new Error(`minRepeats must be >= 2 (got ${n})`);let r=[];for(let o of e){let i=__e(o,n);r.push(...i)}return r}function __e(e,t){let n=I_e(e.events),r=P_e(n),o=[];for(let[i,s]of r.entries()){let a=M_e(s,t);for(let l of a)o.push($_e(e,l,i))}return o}function I_e(e){let t=new Map,n=[];for(let r of e){let o=r.event;if(o.kind!=="tool_call")continue;if(o.payload.phase==="started"){t.set(o.payload.toolUseId,{seq:o.seq,name:o.payload.name,inputBytes:o.payload.inputBytes,subagentId:o.payload.subagentId});continue}let i=t.get(o.payload.toolUseId);if(!i)continue;t.delete(o.payload.toolUseId);let s=O_e({name:o.payload.name,inputBytes:i.inputBytes,resultBytes:o.payload.resultBytes,isError:o.payload.isError,subagentId:i.subagentId});n.push({toolUseId:o.payload.toolUseId,startedSeq:i.seq,completedSeq:o.seq,completedLineNumber:r.lineNumber,name:o.payload.name,inputBytes:i.inputBytes,resultBytes:o.payload.resultBytes,isError:o.payload.isError,subagentId:i.subagentId,rawLine:r.rawLine,fingerprint:s})}return n}function P_e(e){let t=new Map;for(let n of e){let r=n.subagentId??"root",o=t.get(r);o?o.push(n):t.set(r,[n])}return t}function M_e(e,t){let n=[],r=0;for(;r<e.length;){let o=e[r];if(!o){r+=1;continue}let i=r+1;for(;i<e.length;){let a=e[i];if(!a||a.fingerprint!==o.fingerprint)break;i+=1}i-r>=t&&n.push(e.slice(r,i)),r=i>r?i:r+1}return n}function O_e(e){let t=[e.name,String(e.inputBytes),String(e.resultBytes),e.isError?"1":"0",e.subagentId??""].join("|");return x_e("sha256").update(t).digest("hex")}function $_e(e,t,n){let r=t[0];if(!r)throw new Error("repeated-tool-use: empty run");let o=B_e(r.name,r.fingerprint),i=new Date().toISOString(),s=t.slice(0,A_e),a=[{sessionId:e.sessionId,tracePath:e.relativeTracePath,eventIndices:s.map(l=>l.completedSeq),excerpt:D_e(s),annotation:F_e(t,n)}];return{slug:o,title:L_e(r.name,t.length),pattern:"repeated-tool-use",severity:N_e(t.length),observedAt:i,evidence:a,detail:{detector:"repeated-tool-use@v1",fingerprintAlgorithm:C_e,fingerprint:r.fingerprint,toolName:r.name,runLength:t.length,agentContext:n,inputBytes:r.inputBytes,resultBytes:r.resultBytes,isError:r.isError,toolUseIds:t.map(l=>l.toolUseId),completedSeqs:t.map(l=>l.completedSeq)}}}function D_e(e){let t=e.map(n=>n.rawLine).join(`
2067
- `);return t.length<=2e3?t:t.slice(0,1997)+"..."}function F_e(e,t){let n=e[0],r=e[e.length-1];return!n||!r?"":[`${e.length}\xD7 consecutive '${n.name}' calls in ${t} context`,`(seq ${n.completedSeq}\u2026${r.completedSeq},`,`inputBytes=${n.inputBytes}, resultBytes=${n.resultBytes},`,`isError=${n.isError})`].join(" ")}function L_e(e,t){return`'${e}' tool repeated ${t}\xD7 with identical fingerprint`}function N_e(e){return e>=10?"high":e>=4?"medium":"low"}function B_e(e,t){let n=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,""),r=t.slice(0,12);return`repeated-tool-${n.length>0?n:"tool"}-${r}`}var U_e=new Set(["budget_exceeded","timeout","hook_blocked","abort","iteration_cap","max_turns_exceeded"]);function rv(e,t={}){let n=t.minOccurrences??1;if(n<1)throw new Error(`minOccurrences must be >= 1 (got ${n})`);let r=new Map;for(let i of e)for(let s of i.events){let a=s.event;if(a.kind!=="closure")continue;let l=a.payload.reason;if(!U_e.has(l))continue;let c={sessionId:i.sessionId,relativeTracePath:i.relativeTracePath,seq:a.seq,rawLine:s.rawLine,reason:l,finalCostUsd:a.payload.finalCostUsd,finalTurnCount:a.payload.finalTurnCount},u=r.get(l);u?u.push(c):r.set(l,[c])}let o=[];for(let[i,s]of r.entries()){let a=j_e(s);a.length<n||o.push(W_e(i,a,s))}return o}function j_e(e){return[...new Set(e.map(t=>t.sessionId))]}var H_e=8;function W_e(e,t,n){let r=G_e(e),o=new Date().toISOString(),i=n.slice(0,H_e),s=i.map(c=>({sessionId:c.sessionId,tracePath:c.relativeTracePath,eventIndices:[c.seq],excerpt:q_e(c.rawLine),annotation:`closure.reason='${c.reason}' \xB7 cost=${z_e(c.finalCostUsd)} \xB7 turns=${c.finalTurnCount}`})),a=n.reduce((c,u)=>c+u.finalCostUsd,0),l=n.reduce((c,u)=>c+u.finalTurnCount,0)/n.length;return{slug:r,title:`Session closure reason '${e}' across ${t.length} session${t.length===1?"":"s"}`,pattern:"closure-anomaly",severity:K_e(e,t.length),observedAt:o,evidence:s,detail:{detector:"closure-anomaly@v2",closureReason:e,affectedSessions:t.length,closureEventCount:n.length,totalCostUsd:u6(a),avgTurnCount:J_e(l),maxCostUsd:u6(Math.max(...n.map(c=>c.finalCostUsd))),sessionIds:t,seqs:i.map(c=>c.seq)}}}function K_e(e,t){switch(e){case"budget_exceeded":case"timeout":return"high";case"hook_blocked":case"iteration_cap":case"max_turns_exceeded":return t>=3?"high":"medium";case"abort":return t>=3?"medium":"low";default:return"low"}}function G_e(e){let t=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");return`closure-anomaly-${t.length>0?t:"unknown"}`}function q_e(e){return e.length<=2e3?e:e.slice(0,1997)+"..."}function z_e(e){return`$${e.toFixed(4)}`}function u6(e){return Math.round(e*1e4)/1e4}function J_e(e){return Math.round(e*100)/100}import{createHash as V_e}from"crypto";var la=2,Y_e="v1-hook-reason-tuple",X_e=8;function d6(e,t={}){let n=t.minOccurrences??la;if(n<1)throw new Error(`minOccurrences must be >= 1 (got ${n})`);let r=new Map;for(let i of e)for(let s of i.events){let a=s.event;if(a.kind!=="hook_decision"||a.payload.hookEvent!=="SubagentStart"||a.payload.decision!=="block")continue;let l=a.payload.reason??"",c=a.payload.blockedTool,u=Q_e({hookEvent:a.payload.hookEvent,reason:l,blockedTool:c}),d={sessionId:i.sessionId,relativeTracePath:i.relativeTracePath,seq:a.seq,rawLine:s.rawLine,reason:l,blockedTool:c,injectedContextBytes:a.payload.injectedContextBytes},p=r.get(u);p?p.push(d):r.set(u,[d])}let o=[];for(let[i,s]of r.entries())s.length<n||o.push(eIe(i,s));return o}function Q_e(e){let t=[e.hookEvent,e.reason,e.blockedTool??""].join("|");return V_e("sha256").update(t).digest("hex")}function Z_e(e){return`subagent-block-${e.slice(0,12)}`}function eIe(e,t){let n=t[0];if(!n)throw new Error("subagent-block: empty sighting bucket");let r=Z_e(e),o=new Date().toISOString(),s=t.slice(0,X_e).map(l=>({sessionId:l.sessionId,tracePath:l.relativeTracePath,eventIndices:[l.seq],excerpt:oIe(l.rawLine),annotation:rIe(l)})),a=new Set(t.map(l=>l.sessionId)).size;return{slug:r,title:nIe(n.reason,t.length,a),pattern:"subagent-block",severity:tIe(t.length,a),observedAt:o,evidence:s,detail:{detector:"subagent-block@v1",fingerprintAlgorithm:Y_e,fingerprint:e,hookEvent:"SubagentStart",reason:n.reason,blockedTool:n.blockedTool??null,blockCount:t.length,distinctSessions:a,sessionIds:t.map(l=>l.sessionId),seqs:t.map(l=>l.seq)}}}function tIe(e,t){return e>=6||t>=3?"high":e>=3?"medium":"low"}function nIe(e,t,n){let r=e.length>80?e.slice(0,77)+"...":e,o=r.length>0?`: "${r}"`:"";return`SubagentStart hook blocked ${t}\xD7 across ${n} session${n===1?"":"s"}${o}`}function rIe(e){let t=[`seq ${e.seq}`];return e.reason&&t.push(`reason="${e.reason.slice(0,200)}"`),e.blockedTool&&t.push(`blockedTool=${e.blockedTool}`),typeof e.injectedContextBytes=="number"&&t.push(`injectedContextBytes=${e.injectedContextBytes}`),t.join(" \xB7 ")}function oIe(e){return e.length<=2e3?e:e.slice(0,1997)+"..."}import{createHash as iIe}from"crypto";var ca=2,sIe="v1-pretooluse-read-normreason",aIe=8,lIe=new Set(["read_file","grep","glob","list_directory","Read","Grep","Glob","LS","NotebookRead"]);function cIe(e){return e.includes("read-denylist entry:")||e.includes("is a protected credential/secret path")?"credential-floor":e.includes("Sub-agent path access denied:")||e.includes("Sub-agents cannot access paths outside the session's granted roots")?"read-root-containment":"unclassified"}function uIe(e){return e.replace(/~?\/[\w.\-/]+/g,"<path>")}function p6(e,t={}){let n=t.minOccurrences??ca;if(n<1)throw new Error(`minOccurrences must be >= 1 (got ${n})`);let r=new Map;for(let i of e)for(let s of i.events){let a=s.event;if(a.kind!=="hook_decision"||a.payload.hookEvent!=="PreToolUse"||a.payload.decision!=="block")continue;let l=a.payload.blockedTool;if(l===void 0||!lIe.has(l))continue;let c=a.payload.reason??"",u=cIe(c);if(u==="credential-floor")continue;let d=uIe(c),p=dIe({hookEvent:a.payload.hookEvent,normalizedReason:d}),f={sessionId:i.sessionId,relativeTracePath:i.relativeTracePath,seq:a.seq,rawLine:s.rawLine,reason:c,normalizedReason:d,blockedTool:l,mechanism:u},g=r.get(p);g?g.push(f):r.set(p,[f])}let o=[];for(let[i,s]of r.entries())s.length<n||o.push(mIe(i,s));return o}function dIe(e){let t=[e.hookEvent,e.normalizedReason].join("|");return iIe("sha256").update(t).digest("hex")}function pIe(e){return`subagent-read-denial-${e.slice(0,12)}`}function mIe(e,t){let n=t[0];if(!n)throw new Error("subagent-read-denial: empty sighting bucket");let r=pIe(e),o=new Date().toISOString(),s=t.slice(0,aIe).map(c=>({sessionId:c.sessionId,tracePath:c.relativeTracePath,eventIndices:[c.seq],excerpt:yIe(c.rawLine),annotation:hIe(c)})),a=new Set(t.map(c=>c.sessionId)).size,l=[...new Set(t.map(c=>c.blockedTool))].sort();return{slug:r,title:gIe(t.length,a),pattern:"subagent-read-denial",severity:fIe(t.length,a),observedAt:o,evidence:s,detail:{detector:"subagent-read-denial@v2",fingerprintAlgorithm:sIe,fingerprint:e,hookEvent:"PreToolUse",denialMechanism:n.mechanism,normalizedReason:n.normalizedReason,reason:n.reason,blockedTools:l,denialCount:t.length,distinctSessions:a,sessionIds:[...new Set(t.map(c=>c.sessionId))],seqs:t.map(c=>c.seq)}}}function fIe(e,t){return e>=6||t>=3?"high":e>=3?"medium":"low"}function gIe(e,t){return`Forked sub-agent read auto-denied ${e}\xD7 across ${t} session${t===1?"":"s"} (path outside granted read roots)`}function hIe(e){let t=[`seq ${e.seq}`,`blockedTool=${e.blockedTool}`];return e.reason&&t.push(`reason="${e.reason.slice(0,200)}"`),t.join(" \xB7 ")}function yIe(e){return e.length<=2e3?e:e.slice(0,1997)+"..."}var bIe=cb,ua=3,da=.25,wIe=8;function Gc(e,t={}){let n=t.minFailures??ua,r=t.minFailureRate??da;if(n<1)throw new Error(`minFailures must be >= 1 (got ${n})`);if(r<=0||r>1)throw new Error(`minFailureRate must be in (0, 1] (got ${r})`);let o=new Map;for(let s of e)for(let a of s.events){let l=a.event;if(l.kind!=="tool_call"||l.payload.phase!=="completed"||l.payload.circuitBreaker===!0)continue;let c=SIe(o,l.payload.name),u=l.payload.failureClass;if(u!==void 0&&bIe.has(u)){c.excludedByClass.set(u,(c.excludedByClass.get(u)??0)+1);continue}c.totalCalls+=1,l.payload.isError&&(c.failures.push({sessionId:s.sessionId,relativeTracePath:s.relativeTracePath,seq:l.seq,rawLine:a.rawLine,resultBytes:l.payload.resultBytes,durationMs:l.payload.durationMs,truncated:l.payload.truncated,...u!==void 0?{failureClass:u}:{}}),c.affectedSessions.add(s.sessionId),l.payload.truncated&&(c.truncatedFailureCount+=1))}let i=[];for(let s of o.values()){if(s.failures.length<n)continue;let a=s.failures.length/s.totalCalls;a<r||i.push(vIe(s,a))}return i.sort((s,a)=>s.slug.localeCompare(a.slug)),i}function SIe(e,t){let n=e.get(t);return n||(n={toolName:t,totalCalls:0,failures:[],affectedSessions:new Set,truncatedFailureCount:0,excludedByClass:new Map},e.set(t,n)),n}function vIe(e,t){let n=EIe(e.toolName),r=new Date().toISOString(),i=e.failures.slice(0,wIe).map(u=>({sessionId:u.sessionId,tracePath:u.relativeTracePath,eventIndices:[u.seq],excerpt:RIe(u.rawLine),annotation:`isError=true${u.failureClass?` \xB7 class=${u.failureClass}`:""} \xB7 resultBytes=${u.resultBytes} \xB7 durationMs=${u.durationMs}${u.truncated?" \xB7 truncated":""}`})),a=e.failures.reduce((u,d)=>u+d.durationMs,0)/e.failures.length,l={};for(let u of e.failures){let d=u.failureClass??"unclassified";l[d]=(l[d]??0)+1}let c={};for(let[u,d]of e.excludedByClass)c[u]=d;return{slug:n,title:TIe(e.toolName,e.failures.length,e.totalCalls,t),pattern:"tool-failure-density",severity:kIe(e.failures.length,t),observedAt:r,evidence:i,detail:{detector:"tool-failure-density@v2",toolName:e.toolName,totalCalls:e.totalCalls,failureCount:e.failures.length,failureRate:xIe(t),affectedSessionCount:e.affectedSessions.size,truncatedFailureCount:e.truncatedFailureCount,avgFailureDurationMs:AIe(a),failureClassBreakdown:l,excludedByClass:c,sessionIds:Array.from(e.affectedSessions),seqs:e.failures.map(u=>u.seq)}}}function kIe(e,t){return t>=1||t>=.5?"high":t>=.25?e>=10?"high":"medium":e>=10?"medium":"low"}function TIe(e,t,n,r){let o=(r*100).toFixed(1);return`'${e}' tool failed ${t}/${n} calls (${o}%)`}function EIe(e){let t=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");return`tool-failure-${t.length>0?t:"unknown"}`}function RIe(e){return e.length<=2e3?e:e.slice(0,1997)+"..."}function xIe(e){return Math.round(e*1e4)/1e4}function AIe(e){return Math.round(e*100)/100}var ov=Object.freeze([{name:"repeated-tool-use",description:`Tool fired \u2265N consecutive times with identical fingerprint (default ${vo})`,run:(e,t)=>nv(e,{minRepeats:t.minRepeats??vo})},{name:"closure-anomaly",description:`Session closure reason \u2208 {budget_exceeded,timeout,hook_blocked,abort,iteration_cap,max_turns_exceeded} (default \u2265${1})`,enabledByDefault:!0,run:(e,t)=>rv(e,{minOccurrences:t.closureAnomalyMinOccurrences??1})},{name:"subagent-block",description:`Same SubagentStart hook block reason recurring across \u2265N events (default ${la})`,enabledByDefault:!1,run:(e,t)=>d6(e,{minOccurrences:t.subagentBlockMinOccurrences??la})},{name:"tool-failure-density",description:`Tool with \u2265N failures (isError: true) AND failure rate \u2265R (defaults: ${ua} failures, ${da} rate)`,enabledByDefault:!0,run:(e,t)=>Gc(e,{minFailures:t.toolFailureMinFailures??ua,minFailureRate:t.toolFailureMinRate??da})},{name:"subagent-read-denial",description:`Forked sub-agent read auto-denied (PreToolUse block, path outside granted read roots) recurring across \u2265N events (default ${ca})`,enabledByDefault:!1,run:(e,t)=>p6(e,{minOccurrences:t.subagentReadDenialMinOccurrences??ca})}]);function m6(e,t,n,r){let o=[];for(let i of ov){if(n!==void 0){if(!n.has(i.name))continue}else if(r!==!0&&i.enabledByDefault===!1)continue;let s=i.run(e,t);o.push(...s)}return o}function iv(){return ov.map(e=>e.name)}function f6(){return ov.filter(e=>e.enabledByDefault!==!1).map(e=>e.name)}function qc(){return ov.filter(e=>e.enabledByDefault===!1).map(e=>e.name)}import{existsSync as fm,mkdirSync as R6,readFileSync as qIe,readdirSync as x6,writeFileSync as zIe}from"fs";import{join as A6}from"path";import{z as L}from"zod";var Pi=L.enum(["repeated-tool-use","subagent-block","closure-anomaly","tool-failure-density","subagent-read-denial"]),sv=L.enum(["low","medium","high"]),CIe=L.enum(["open","deferred","resolved"]),g6=L.object({sessionId:L.string().min(1),tracePath:L.string().min(1),eventIndices:L.array(L.number().int().nonnegative()).min(1),excerpt:L.string().max(2e3),annotation:L.string().optional()}),av=L.object({at:L.string().datetime(),text:L.string()}),mm=L.object({schemaVersion:L.literal(1),slug:L.string().regex(/^[a-z0-9][a-z0-9-]*$/,"slug must be lowercase alphanumeric with hyphens"),title:L.string().min(1).max(200),pattern:Pi,severity:sv,status:CIe,firstSeen:L.string().datetime(),lastSeen:L.string().datetime(),occurrenceCount:L.number().int().nonnegative(),evidence:L.array(g6).min(1),detail:L.record(L.string(),L.unknown()),notes:L.array(av).default([])}),FMt=L.object({slug:L.string().regex(/^[a-z0-9][a-z0-9-]*$/),title:L.string().min(1).max(200),pattern:Pi,severity:sv,observedAt:L.string().datetime(),evidence:L.array(g6).min(1),detail:L.record(L.string(),L.unknown())}),h6=L.object({timestamp:L.string().datetime(),event:L.enum(["created","updated","merged-noop"]),slug:L.string(),pattern:Pi,occurrenceCount:L.number().int().nonnegative(),evidenceAdded:L.number().int().nonnegative()}),_Ie=L.enum(["prompt-defect","schema-too-strict","schema-too-loose","tool-output-shape","hook-overreach","retry-policy","timeout-too-low","cost-control","dispatcher-bug","detector-needs-tuning","unknown"]),IIe=L.enum(["safe","moderate","high","forbidden"]),PIe=L.enum(["low","medium","high"]),MIe=L.object({cardSlug:L.string(),eventIndices:L.array(L.number().int().nonnegative()).min(1),annotation:L.string().optional()}),OIe=L.object({path:L.string().min(1),rationale:L.string(),riskTier:IIe,confidence:PIe}),$Ie=L.object({unitTests:L.array(L.string()),evalCases:L.array(L.string()),smokeChecks:L.array(L.string()),manualChecks:L.array(L.string())}),DIe=L.object({forbiddenPaths:L.array(L.string()),requiresExplicitApproval:L.boolean()}),FIe=L.enum(["draft","approved","rejected","superseded"]),lI=L.object({schemaVersion:L.literal(1),proposalId:L.string().regex(/^[a-z0-9][a-z0-9-]*$/),cardSlug:L.string().regex(/^[a-z0-9][a-z0-9-]*$/),title:L.string().min(1).max(200),hypothesis:L.string().min(1),rootCauseClass:_Ie,evidenceRefs:L.array(MIe).min(1),fixSketch:L.string().min(1),likelyFiles:L.array(OIe),riskLevel:sv,validationPlan:$Ie,scopeFreeze:DIe,generatedBy:L.enum(["template","llm"]),createdAt:L.string().datetime(),status:FIe,notes:L.array(av).default([])}),y6=L.object({timestamp:L.string().datetime(),event:L.enum(["created","triaged","superseded"]),proposalId:L.string(),cardSlug:L.string(),generatedBy:L.enum(["template","llm"]),riskLevel:sv}),LIe=L.object({sourceSessionId:L.string().min(1),sourceTracePath:L.string().min(1),fixturePath:L.string().min(1),evidenceRowIndex:L.number().int().nonnegative(),evidenceEventIndices:L.array(L.number().int().nonnegative()).min(1),sliceLineRange:L.object({startLine:L.number().int().positive(),endLine:L.number().int().positive()}),sliceLineCount:L.number().int().positive(),sliceSha256:L.string().regex(/^[0-9a-f]{64}$/,"sliceSha256 must be 64 lowercase hex chars")}),NIe=L.object({kind:L.literal("pattern-absent"),patternId:Pi,detectorVersion:L.string().min(1),rationale:L.string().min(1)}),BIe=L.object({detectorAtGeneration:L.string().min(1),fingerprintAtGeneration:L.string().nullable(),cardOccurrenceCountAtGeneration:L.number().int().nonnegative(),cardLastSeenAtGeneration:L.string().datetime(),generatedBy:L.literal("replay-fixture")}),UIe=L.enum(["draft","approved","rejected","superseded"]),lv=L.object({schemaVersion:L.literal(1),evalCaseId:L.string().regex(/^[a-z0-9][a-z0-9-]*$/,"evalCaseId must be lowercase alphanumeric with hyphens"),cardSlug:L.string().regex(/^[a-z0-9][a-z0-9-]*$/),proposalId:L.string().regex(/^[a-z0-9][a-z0-9-]*$/).nullable(),title:L.string().min(1).max(200),createdAt:L.string().datetime(),kind:L.literal("replay"),replay:LIe,assertion:NIe,provenance:BIe,status:UIe,notes:L.array(av).default([])}),b6=L.object({timestamp:L.string().datetime(),event:L.enum(["created","triaged","superseded"]),evalCaseId:L.string(),cardSlug:L.string(),proposalId:L.string().nullable(),kind:L.literal("replay")}),jIe=L.enum(["pass","fail","skipped"]),HIe=L.object({name:L.string().min(1),description:L.string().min(1),status:jIe,expected:L.string(),actual:L.string()}),WIe=L.enum(["config-value","observed-behavior","source-symbol","fixture"]),KIe=L.object({kind:WIe,ref:L.string().min(1),detail:L.string()}),w6=L.enum(["pass","fail","unsupported","error"]),cI=L.object({schemaVersion:L.literal(1),evalRunId:L.string().regex(/^[a-z0-9][a-z0-9-]*$/,"evalRunId must be lowercase alphanumeric with hyphens"),evalCaseId:L.string().min(1),cardSlug:L.string().min(1),patternId:Pi,contract:L.string().min(1).nullable(),status:w6,createdAt:L.string().datetime(),durationMs:L.number().int().nonnegative(),checks:L.array(HIe),evidence:L.array(KIe),runner:L.object({version:L.string().min(1),mode:L.literal("deterministic")}),notes:L.array(av).default([])}),S6=L.object({timestamp:L.string().datetime(),event:L.literal("created"),evalRunId:L.string(),evalCaseId:L.string(),cardSlug:L.string(),patternId:Pi,contract:L.string().nullable(),status:w6}),v6=Object.freeze(["**/auth/**","**/billing/**","**/secrets/**","**/credentials*",".env",".env.*","pnpm-lock.yaml","package-lock.json","yarn.lock",".github/workflows/**","dist/**","build/**","node_modules/**",".git/**","**/.afk/config/**","**/.afk/state/**"]);var k6={low:0,medium:1,high:2};function GIe(e,t){return k6[e]>=k6[t]?e:t}function T6(e){let t=e?.detector;return typeof t=="string"&&t.length>0?t:void 0}function E6(e,t){let n=T6(e.detail),r=T6(t.detail);return n!==void 0&&r!==void 0&&n!==r?t.severity:GIe(e.severity,t.severity)}zr();function C6(e){let t=_i();fm(t)||R6(t,{recursive:!0});let n=dm(e.slug),r=tv(e.slug),o=zc(n),i=JIe(o,e),s=o===void 0,a=i.evidence.length-(o?.evidence.length??0),l=s?"created":a>0?"updated":"merged-noop",c=mm.parse(i);return Ze(n,JSON.stringify(c,null,2),438),Ze(r,gm(c),438),YIe({timestamp:XIe(),event:l,slug:c.slug,pattern:c.pattern,occurrenceCount:c.occurrenceCount,evidenceAdded:Math.max(0,a)}),{slug:c.slug,event:l,occurrenceCount:c.occurrenceCount,evidenceAdded:Math.max(0,a),jsonPath:n,markdownPath:r}}function zc(e){if(fm(e))try{let t=qIe(e,"utf-8"),n=JSON.parse(t),r=mm.safeParse(n);return r.success?r.data:void 0}catch{return}}function JIe(e,t){if(!e)return{schemaVersion:1,slug:t.slug,title:t.title,pattern:t.pattern,severity:t.severity,status:"open",firstSeen:t.observedAt,lastSeen:t.observedAt,occurrenceCount:t.evidence.length,evidence:t.evidence,detail:t.detail,notes:[]};if(e.slug!==t.slug)throw new Error(`card-writer: slug mismatch on merge (existing='${e.slug}', detection='${t.slug}')`);let n=VIe(e.evidence,t.evidence),r=QIe(e.firstSeen,t.observedAt),o=ZIe(e.lastSeen,t.observedAt),i=E6(e,t);return{schemaVersion:1,slug:e.slug,title:t.title,pattern:e.pattern,severity:i,status:e.status,firstSeen:r,lastSeen:o,occurrenceCount:n.length,evidence:n,detail:t.detail,notes:e.notes}}function VIe(e,t){let n=i=>`${i.sessionId}::${i.eventIndices[0]??"NA"}`,r=new Set(e.map(n)),o=[...e];for(let i of t){let s=n(i);r.has(s)||(r.add(s),o.push(i))}return o}function gm(e){let t=[];t.push(`# ${e.slug} \u2014 \`${e.severity}\` \u2014 \`${e.status}\``),t.push(""),t.push(e.title),t.push(""),t.push(`**Pattern:** \`${e.pattern}\` \xB7 **Occurrences:** ${e.occurrenceCount} \xB7 **First seen:** ${e.firstSeen} \xB7 **Last seen:** ${e.lastSeen}`),t.push(""),t.push("## Evidence"),t.push("");for(let n of e.evidence)t.push(`### Session \`${n.sessionId}\``),t.push(""),t.push(`- Trace: \`${n.tracePath}\``),t.push(`- Event seqs: ${n.eventIndices.join(", ")}`),n.annotation&&t.push(`- Note: ${n.annotation}`),t.push(""),t.push("```jsonl"),t.push(n.excerpt),t.push("```"),t.push("");if(t.push("## Detail"),t.push(""),t.push("```json"),t.push(JSON.stringify(e.detail,null,2)),t.push("```"),t.push(""),t.push("## Triage notes"),t.push(""),e.notes.length>0){for(let n of e.notes)t.push(`- _${n.at}_ \u2014 ${n.text}`);t.push("")}else t.push('_(none \u2014 add one with `afk improve cards triage <slug> --note "\u2026"`)_'),t.push("");return t.join(`
2068
- `)}function YIe(e){let t=h6.parse(e),n=Z5(),r=_i();fm(r)||R6(r,{recursive:!0});try{zIe(n,JSON.stringify(t)+`
2069
- `,{flag:"a"})}catch{}}function XIe(){return new Date().toISOString()}function QIe(e,t){return e<=t?e:t}function ZIe(e,t){return e>=t?e:t}function _6(){let e=_i();if(!fm(e))return[];let t=[];for(let n of x6(e)){if(!n.endsWith(".json")||n.startsWith("."))continue;let r=zc(A6(e,n));r&&t.push({slug:r.slug,title:r.title,pattern:r.pattern,severity:r.severity,status:r.status,occurrenceCount:r.occurrenceCount,firstSeen:r.firstSeen,lastSeen:r.lastSeen})}return t.sort((n,r)=>n.lastSeen!==r.lastSeen?n.lastSeen<r.lastSeen?1:-1:n.slug<r.slug?-1:1),t}function Jc(e){return zc(dm(e))}function I6(e){let t;for(let n of e.notes)(t===void 0||Date.parse(n.at)>Date.parse(t))&&(t=n.at);return t}function ePe(e){if(e.status!=="resolved"&&e.status!=="deferred")return!1;let t=I6(e);if(t===void 0)return!1;let n=Date.parse(e.lastSeen),r=Date.parse(t);return Number.isNaN(n)||Number.isNaN(r)?!1:n>r}function tPe(e){let t=[];for(let n of e){if(!ePe(n))continue;let r=I6(n);r!==void 0&&t.push({slug:n.slug,pattern:n.pattern,severity:n.severity,status:n.status,occurrenceCount:n.occurrenceCount,lastSeen:n.lastSeen,latestNoteAt:r})}return t.sort((n,r)=>n.lastSeen!==r.lastSeen?n.lastSeen<r.lastSeen?1:-1:n.slug<r.slug?-1:1),t}function P6(){let e=_i();if(!fm(e))return[];let t=[];for(let n of x6(e)){if(!n.endsWith(".json")||n.startsWith("."))continue;let r=zc(A6(e,n));r&&t.push(r)}return tPe(t)}function M6(e){e.command("scan").description(`Run registered detectors against witness traces. Dry-run by default.
2070
- Some detectors are disabled by default (pass --include-disabled to enable): ${qc().join(", ")}.`).option("--since <duration>","Only scan sessions newer than this (e.g. 7d, 24h, all)","7d").option("--write","Persist failure cards to disk. Without this flag, scan is dry-run.",!1).option("--min-repeats <n>",`repeated-tool-use threshold (default ${vo})`,String(vo)).option("--closure-min-occurrences <n>",`closure-anomaly threshold (default ${1})`,String(1)).option("--block-min-occurrences <n>",`subagent-block threshold (default ${la})`,String(la)).option("--read-denial-min-occurrences <n>",`subagent-read-denial threshold (default ${ca})`,String(ca)).option("--tool-failure-min-failures <n>",`tool-failure-density absolute count threshold (default ${ua})`,String(ua)).option("--tool-failure-min-rate <rate>",`tool-failure-density rate threshold, 0\u20131 (default ${da})`,String(da)).option("--only <names>",`Comma-separated detector names to run (any of: ${iv().join(", ")})`).option("--include-disabled",`Run detectors marked disabled-by-default (currently: ${qc().join(", ")})`,!1).action(t=>{try{let n=hm(t.minRepeats,"min-repeats",2),r=hm(t.closureMinOccurrences,"closure-min-occurrences",1),o=hm(t.blockMinOccurrences,"block-min-occurrences",1),i=hm(t.readDenialMinOccurrences,"read-denial-min-occurrences",1),s=hm(t.toolFailureMinFailures,"tool-failure-min-failures",1),a=nPe(t.toolFailureMinRate,"tool-failure-min-rate"),l;if(t.only){let w=t.only.split(",").map(E=>E.trim()).filter(E=>E.length>0),k=new Set(iv()),S=w.filter(E=>!k.has(E));S.length>0&&(console.error(`Unknown detector(s): ${S.join(", ")}. Known: ${iv().join(", ")}`),process.exit(2)),l=new Set(w)}let c;if(t.since&&t.since!=="all"){let w=l6(t.since);w===void 0&&(console.error(`Invalid --since: '${t.since}'. Use forms like '7d', '24h', '30m', '3600s', or 'all'.`),process.exit(2)),c=Date.now()-w}let u=c6({sinceMs:c}),d={minRepeats:n,closureAnomalyMinOccurrences:r,subagentBlockMinOccurrences:o,subagentReadDenialMinOccurrences:i,toolFailureMinFailures:s,toolFailureMinRate:a},p=m6(u.sessions,d,l,t.includeDisabled);console.log(`Scanned ${u.sessionsScanned} sessions`),u.sessionsSkippedOld>0&&console.log(` \u21B3 skipped ${u.sessionsSkippedOld} older than --since`),u.sessionsSkippedEmpty>0&&console.log(` \u21B3 skipped ${u.sessionsSkippedEmpty} with missing/unreadable trace.jsonl`),u.invalidLineCount>0&&console.log(` \u26A0 ${u.invalidLineCount} invalid JSONL lines skipped`);let f=qc();!t.only&&!t.includeDisabled&&f.length>0&&console.log(`Skipped ${f.length} detectors (disabled by default \u2014 pass --only or --include-disabled): ${f.join(", ")}`);let g=new Map;for(let w of p)g.set(w.pattern,(g.get(w.pattern)??0)+1);console.log(`Detections: ${p.length}`);for(let[w,k]of g.entries())console.log(` \u21B3 ${w}: ${k}`);if(p.length===0){t.write&&console.log("No cards written.");return}for(let w of p)console.log(` \u2022 ${w.slug} [${w.severity}] ${w.pattern} evidence=${w.evidence.length}`);if(!t.write){console.log(""),console.log("(dry-run \u2014 pass --write to persist cards)");return}let h=0,y=0,b=0;for(let w of p){let k=C6(w);k.event==="created"?h+=1:k.event==="updated"?y+=1:b+=1}console.log(""),console.log(`Wrote cards: ${h} created, ${y} updated, ${b} no-op merges.`)}catch(n){J(n)}})}function hm(e,t,n){let r=Number.parseInt(e,10);return(!Number.isFinite(r)||r<n)&&(console.error(`Invalid --${t}: '${e}' (must be integer >= ${n})`),process.exit(2)),r}function nPe(e,t){let n=Number.parseFloat(e);return(!Number.isFinite(n)||n<=0||n>1)&&(console.error(`Invalid --${t}: '${e}' (must be number in (0, 1])`),process.exit(2)),n}import{existsSync as rPe,mkdirSync as oPe}from"fs";import{dirname as iPe}from"path";zr();var pa=class extends Error{constructor(n,r){super(r);this.code=n;this.name="TriageError"}code};function O6(e,t){let n=dm(e),r=tv(e),o=zc(n);if(!o)throw new pa("card-not-found",`No failure card found for slug '${e}'`);if(t.note!==void 0&&t.note.trim().length===0)throw new pa("invalid-note","triage note must be non-empty after trim");let i=t.note?.trim(),s=i!==void 0&&i.length>0,a=t.status!==void 0&&t.status!==o.status;if(!s&&!a)throw new pa("no-change","triage requires at least --note or --status to differ from current");let l=(t.now??(()=>new Date))().toISOString(),c=s?[...o.notes,{at:l,text:i}]:o.notes,u=a?t.status:o.status,d={...o,status:u,notes:c},p=mm.parse(d);return sPe(n),Ze(n,JSON.stringify(p,null,2),438),Ze(r,gm(p),438),{slug:e,card:p,noteAdded:s,statusChanged:a?{from:o.status,to:u}:void 0,jsonPath:n,markdownPath:r}}function sPe(e){let t=iPe(e);rPe(t)||oPe(t,{recursive:!0})}var uI=["open","deferred","resolved"];function aPe(e){let t=P6();if(e.pattern&&(t=t.filter(o=>o.pattern===e.pattern)),e.severity&&(t=t.filter(o=>o.severity===e.severity)),e.status&&(t=t.filter(o=>o.status===e.status)),e.json){console.log(JSON.stringify(t,null,2));return}if(t.length===0){console.log("No regressed cards found (no resolved/deferred card has fired since its latest triage note).");return}let n="SLUG | PATTERN | SEV | STATUS | N | LAST SEEN | LATEST NOTE",r="-".repeat(n.length);console.log(`${t.length} regressed card(s): triaged, then fired again afterwards.`),console.log(n),console.log(r);for(let o of t)console.log([o.slug.padEnd(50).slice(0,50),o.pattern.padEnd(20),o.severity.padEnd(6),o.status.padEnd(9),String(o.occurrenceCount).padEnd(4),o.lastSeen.padEnd(24),o.latestNoteAt].join(" | "))}function $6(e){let t=e.command("cards").description("Inspect and triage failure cards written by `afk improve scan`");t.command("list").description("List all failure cards, newest first").option("--pattern <name>","Filter by pattern name").option("--severity <level>","Filter by severity: low | medium | high").option("--status <state>","Filter by status: open | deferred | resolved").option("--regressed","Only show resolved/deferred cards that fired again after their latest triage note",!1).option("--json","Emit JSON instead of a table",!1).action(n=>{try{if(n.regressed){aPe(n);return}let r=_6();if(n.pattern&&(r=r.filter(s=>s.pattern===n.pattern)),n.severity&&(r=r.filter(s=>s.severity===n.severity)),n.status&&(r=r.filter(s=>s.status===n.status)),n.json){console.log(JSON.stringify(r,null,2));return}if(r.length===0){console.log("No failure cards found.");return}let o="SLUG | PATTERN | SEV | STATUS | N | LAST SEEN",i="-".repeat(o.length);console.log(o),console.log(i);for(let s of r)console.log([s.slug.padEnd(50).slice(0,50),s.pattern.padEnd(20),s.severity.padEnd(6),s.status.padEnd(9),String(s.occurrenceCount).padEnd(4),s.lastSeen].join(" | "))}catch(r){J(r)}}),t.command("show <slug>").description("Print a failure card by slug").option("--json","Emit raw JSON instead of rendered markdown",!1).action((n,r)=>{try{let o=Jc(n);if(o||(console.error(`Card not found: ${n}`),process.exit(1)),r.json){console.log(JSON.stringify(o,null,2));return}console.log(gm(o))}catch(o){J(o)}}),t.command("triage <slug>").description("Append a human note and/or change status on a failure card").option("--note <text>","Note text to append (non-empty)").option("--status <state>",`New status (one of: ${uI.join(", ")})`).option("--json","Emit the resulting card as JSON",!1).action((n,r)=>{try{let o;r.status!==void 0&&(uI.includes(r.status)||(console.error(`Invalid --status: '${r.status}'. Must be one of: ${uI.join(", ")}`),process.exit(2)),o=r.status);let i=O6(n,{...r.note!==void 0?{note:r.note}:{},...o!==void 0?{status:o}:{}});if(r.json){console.log(JSON.stringify(i.card,null,2));return}let s=[];i.noteAdded&&s.push("note appended"),i.statusChanged&&s.push(`status: ${i.statusChanged.from} \u2192 ${i.statusChanged.to}`),console.log(`Triaged ${n}: ${s.join(" \xB7 ")}`),console.log(` json: ${i.jsonPath}`),console.log(` md: ${i.markdownPath}`)}catch(o){o instanceof pa&&(console.error(`triage failed [${o.code}]: ${o.message}`),process.exit(o.code==="card-not-found"?1:2)),J(o)}})}var lPe={"repeated-tool-use":{rootCauseClass:"dispatcher-bug",hypothesis:e=>{let t=typeof e.detail.toolName=="string"?e.detail.toolName:"<unknown>",n=typeof e.detail.runLength=="number"?e.detail.runLength:"?";return`The '${t}' tool was dispatched ${n} times in a row with an identical input/output byte fingerprint. This is either (a) the model is stuck retrying the same call without responding to its result, (b) the tool's result shape is too uninformative for the model to make progress, or (c) a productive recursion that happens to share byte counts (rare; the fingerprint caveat is documented on the detector).`},fixSketch:e=>["## Candidate fixes (human picks)","",`**Option A \u2014 make the loop visible.** Surface a clear "no-progress" signal to the model when '${typeof e.detail.toolName=="string"?e.detail.toolName:"<the tool>"}' returns the same result N times in a row. Today the dispatcher just executes the call.`,"",`**Option B \u2014 improve the tool's result shape.** If the model can't distinguish "no results" from "same results," its result is information-poor. Inspect the tool's response and verify it carries enough signal for the model to change its query.`,"","**Option C \u2014 confirm productive recursion.** Open the source trace at the seq values listed in the evidence and inspect the model's reasoning between repeats. If each call's args genuinely differ (and the byte-count collision is the issue), no code change is needed; tune the detector instead.","","_Option C first \u2014 the byte-fingerprint detector has a documented collision caveat. Confirm there is a real loop before changing dispatcher behavior._"].join(`
2067
+ `);return t.length<=2e3?t:t.slice(0,1997)+"..."}function F_e(e,t){let n=e[0],r=e[e.length-1];return!n||!r?"":[`${e.length}\xD7 consecutive '${n.name}' calls in ${t} context`,`(seq ${n.completedSeq}\u2026${r.completedSeq},`,`inputBytes=${n.inputBytes}, resultBytes=${n.resultBytes},`,`isError=${n.isError})`].join(" ")}function L_e(e,t){return`'${e}' tool repeated ${t}\xD7 with identical fingerprint`}function N_e(e){return e>=10?"high":e>=4?"medium":"low"}function B_e(e,t){let n=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,""),r=t.slice(0,12);return`repeated-tool-${n.length>0?n:"tool"}-${r}`}var U_e=new Set(["budget_exceeded","timeout","hook_blocked","abort","iteration_cap","max_turns_exceeded"]);function rv(e,t={}){let n=t.minOccurrences??1;if(n<1)throw new Error(`minOccurrences must be >= 1 (got ${n})`);let r=new Map;for(let i of e)for(let s of i.events){let a=s.event;if(a.kind!=="closure")continue;let l=a.payload.reason;if(!U_e.has(l))continue;let c={sessionId:i.sessionId,relativeTracePath:i.relativeTracePath,seq:a.seq,rawLine:s.rawLine,reason:l,finalCostUsd:a.payload.finalCostUsd,finalTurnCount:a.payload.finalTurnCount},u=r.get(l);u?u.push(c):r.set(l,[c])}let o=[];for(let[i,s]of r.entries()){let a=j_e(s);a.length<n||o.push(W_e(i,a,s))}return o}function j_e(e){return[...new Set(e.map(t=>t.sessionId))]}var H_e=8;function W_e(e,t,n){let r=G_e(e),o=new Date().toISOString(),i=n.slice(0,H_e),s=i.map(c=>({sessionId:c.sessionId,tracePath:c.relativeTracePath,eventIndices:[c.seq],excerpt:q_e(c.rawLine),annotation:`closure.reason='${c.reason}' \xB7 cost=${z_e(c.finalCostUsd)} \xB7 turns=${c.finalTurnCount}`})),a=n.reduce((c,u)=>c+u.finalCostUsd,0),l=n.reduce((c,u)=>c+u.finalTurnCount,0)/n.length;return{slug:r,title:`Session closure reason '${e}' across ${t.length} session${t.length===1?"":"s"}`,pattern:"closure-anomaly",severity:K_e(e,t.length),observedAt:o,evidence:s,detail:{detector:"closure-anomaly@v2",closureReason:e,affectedSessions:t.length,closureEventCount:n.length,totalCostUsd:u5(a),avgTurnCount:J_e(l),maxCostUsd:u5(Math.max(...n.map(c=>c.finalCostUsd))),sessionIds:t,seqs:i.map(c=>c.seq)}}}function K_e(e,t){switch(e){case"budget_exceeded":case"timeout":return"high";case"hook_blocked":case"iteration_cap":case"max_turns_exceeded":return t>=3?"high":"medium";case"abort":return t>=3?"medium":"low";default:return"low"}}function G_e(e){let t=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");return`closure-anomaly-${t.length>0?t:"unknown"}`}function q_e(e){return e.length<=2e3?e:e.slice(0,1997)+"..."}function z_e(e){return`$${e.toFixed(4)}`}function u5(e){return Math.round(e*1e4)/1e4}function J_e(e){return Math.round(e*100)/100}import{createHash as V_e}from"crypto";var la=2,Y_e="v1-hook-reason-tuple",X_e=8;function d5(e,t={}){let n=t.minOccurrences??la;if(n<1)throw new Error(`minOccurrences must be >= 1 (got ${n})`);let r=new Map;for(let i of e)for(let s of i.events){let a=s.event;if(a.kind!=="hook_decision"||a.payload.hookEvent!=="SubagentStart"||a.payload.decision!=="block")continue;let l=a.payload.reason??"",c=a.payload.blockedTool,u=Q_e({hookEvent:a.payload.hookEvent,reason:l,blockedTool:c}),d={sessionId:i.sessionId,relativeTracePath:i.relativeTracePath,seq:a.seq,rawLine:s.rawLine,reason:l,blockedTool:c,injectedContextBytes:a.payload.injectedContextBytes},p=r.get(u);p?p.push(d):r.set(u,[d])}let o=[];for(let[i,s]of r.entries())s.length<n||o.push(eIe(i,s));return o}function Q_e(e){let t=[e.hookEvent,e.reason,e.blockedTool??""].join("|");return V_e("sha256").update(t).digest("hex")}function Z_e(e){return`subagent-block-${e.slice(0,12)}`}function eIe(e,t){let n=t[0];if(!n)throw new Error("subagent-block: empty sighting bucket");let r=Z_e(e),o=new Date().toISOString(),s=t.slice(0,X_e).map(l=>({sessionId:l.sessionId,tracePath:l.relativeTracePath,eventIndices:[l.seq],excerpt:oIe(l.rawLine),annotation:rIe(l)})),a=new Set(t.map(l=>l.sessionId)).size;return{slug:r,title:nIe(n.reason,t.length,a),pattern:"subagent-block",severity:tIe(t.length,a),observedAt:o,evidence:s,detail:{detector:"subagent-block@v1",fingerprintAlgorithm:Y_e,fingerprint:e,hookEvent:"SubagentStart",reason:n.reason,blockedTool:n.blockedTool??null,blockCount:t.length,distinctSessions:a,sessionIds:t.map(l=>l.sessionId),seqs:t.map(l=>l.seq)}}}function tIe(e,t){return e>=6||t>=3?"high":e>=3?"medium":"low"}function nIe(e,t,n){let r=e.length>80?e.slice(0,77)+"...":e,o=r.length>0?`: "${r}"`:"";return`SubagentStart hook blocked ${t}\xD7 across ${n} session${n===1?"":"s"}${o}`}function rIe(e){let t=[`seq ${e.seq}`];return e.reason&&t.push(`reason="${e.reason.slice(0,200)}"`),e.blockedTool&&t.push(`blockedTool=${e.blockedTool}`),typeof e.injectedContextBytes=="number"&&t.push(`injectedContextBytes=${e.injectedContextBytes}`),t.join(" \xB7 ")}function oIe(e){return e.length<=2e3?e:e.slice(0,1997)+"..."}import{createHash as iIe}from"crypto";var ca=2,sIe="v1-pretooluse-read-normreason",aIe=8,lIe=new Set(["read_file","grep","glob","list_directory","Read","Grep","Glob","LS","NotebookRead"]);function cIe(e){return e.includes("read-denylist entry:")||e.includes("is a protected credential/secret path")?"credential-floor":e.includes("Sub-agent path access denied:")||e.includes("Sub-agents cannot access paths outside the session's granted roots")?"read-root-containment":"unclassified"}function uIe(e){return e.replace(/~?\/[\w.\-/]+/g,"<path>")}function p5(e,t={}){let n=t.minOccurrences??ca;if(n<1)throw new Error(`minOccurrences must be >= 1 (got ${n})`);let r=new Map;for(let i of e)for(let s of i.events){let a=s.event;if(a.kind!=="hook_decision"||a.payload.hookEvent!=="PreToolUse"||a.payload.decision!=="block")continue;let l=a.payload.blockedTool;if(l===void 0||!lIe.has(l))continue;let c=a.payload.reason??"",u=cIe(c);if(u==="credential-floor")continue;let d=uIe(c),p=dIe({hookEvent:a.payload.hookEvent,normalizedReason:d}),f={sessionId:i.sessionId,relativeTracePath:i.relativeTracePath,seq:a.seq,rawLine:s.rawLine,reason:c,normalizedReason:d,blockedTool:l,mechanism:u},g=r.get(p);g?g.push(f):r.set(p,[f])}let o=[];for(let[i,s]of r.entries())s.length<n||o.push(mIe(i,s));return o}function dIe(e){let t=[e.hookEvent,e.normalizedReason].join("|");return iIe("sha256").update(t).digest("hex")}function pIe(e){return`subagent-read-denial-${e.slice(0,12)}`}function mIe(e,t){let n=t[0];if(!n)throw new Error("subagent-read-denial: empty sighting bucket");let r=pIe(e),o=new Date().toISOString(),s=t.slice(0,aIe).map(c=>({sessionId:c.sessionId,tracePath:c.relativeTracePath,eventIndices:[c.seq],excerpt:yIe(c.rawLine),annotation:hIe(c)})),a=new Set(t.map(c=>c.sessionId)).size,l=[...new Set(t.map(c=>c.blockedTool))].sort();return{slug:r,title:gIe(t.length,a),pattern:"subagent-read-denial",severity:fIe(t.length,a),observedAt:o,evidence:s,detail:{detector:"subagent-read-denial@v2",fingerprintAlgorithm:sIe,fingerprint:e,hookEvent:"PreToolUse",denialMechanism:n.mechanism,normalizedReason:n.normalizedReason,reason:n.reason,blockedTools:l,denialCount:t.length,distinctSessions:a,sessionIds:[...new Set(t.map(c=>c.sessionId))],seqs:t.map(c=>c.seq)}}}function fIe(e,t){return e>=6||t>=3?"high":e>=3?"medium":"low"}function gIe(e,t){return`Forked sub-agent read auto-denied ${e}\xD7 across ${t} session${t===1?"":"s"} (path outside granted read roots)`}function hIe(e){let t=[`seq ${e.seq}`,`blockedTool=${e.blockedTool}`];return e.reason&&t.push(`reason="${e.reason.slice(0,200)}"`),t.join(" \xB7 ")}function yIe(e){return e.length<=2e3?e:e.slice(0,1997)+"..."}var bIe=cb,ua=3,da=.25,wIe=8;function Gc(e,t={}){let n=t.minFailures??ua,r=t.minFailureRate??da;if(n<1)throw new Error(`minFailures must be >= 1 (got ${n})`);if(r<=0||r>1)throw new Error(`minFailureRate must be in (0, 1] (got ${r})`);let o=new Map;for(let s of e)for(let a of s.events){let l=a.event;if(l.kind!=="tool_call"||l.payload.phase!=="completed"||l.payload.circuitBreaker===!0)continue;let c=SIe(o,l.payload.name),u=l.payload.failureClass;if(u!==void 0&&bIe.has(u)){c.excludedByClass.set(u,(c.excludedByClass.get(u)??0)+1);continue}c.totalCalls+=1,l.payload.isError&&(c.failures.push({sessionId:s.sessionId,relativeTracePath:s.relativeTracePath,seq:l.seq,rawLine:a.rawLine,resultBytes:l.payload.resultBytes,durationMs:l.payload.durationMs,truncated:l.payload.truncated,...u!==void 0?{failureClass:u}:{}}),c.affectedSessions.add(s.sessionId),l.payload.truncated&&(c.truncatedFailureCount+=1))}let i=[];for(let s of o.values()){if(s.failures.length<n)continue;let a=s.failures.length/s.totalCalls;a<r||i.push(vIe(s,a))}return i.sort((s,a)=>s.slug.localeCompare(a.slug)),i}function SIe(e,t){let n=e.get(t);return n||(n={toolName:t,totalCalls:0,failures:[],affectedSessions:new Set,truncatedFailureCount:0,excludedByClass:new Map},e.set(t,n)),n}function vIe(e,t){let n=EIe(e.toolName),r=new Date().toISOString(),i=e.failures.slice(0,wIe).map(u=>({sessionId:u.sessionId,tracePath:u.relativeTracePath,eventIndices:[u.seq],excerpt:RIe(u.rawLine),annotation:`isError=true${u.failureClass?` \xB7 class=${u.failureClass}`:""} \xB7 resultBytes=${u.resultBytes} \xB7 durationMs=${u.durationMs}${u.truncated?" \xB7 truncated":""}`})),a=e.failures.reduce((u,d)=>u+d.durationMs,0)/e.failures.length,l={};for(let u of e.failures){let d=u.failureClass??"unclassified";l[d]=(l[d]??0)+1}let c={};for(let[u,d]of e.excludedByClass)c[u]=d;return{slug:n,title:TIe(e.toolName,e.failures.length,e.totalCalls,t),pattern:"tool-failure-density",severity:kIe(e.failures.length,t),observedAt:r,evidence:i,detail:{detector:"tool-failure-density@v2",toolName:e.toolName,totalCalls:e.totalCalls,failureCount:e.failures.length,failureRate:xIe(t),affectedSessionCount:e.affectedSessions.size,truncatedFailureCount:e.truncatedFailureCount,avgFailureDurationMs:AIe(a),failureClassBreakdown:l,excludedByClass:c,sessionIds:Array.from(e.affectedSessions),seqs:e.failures.map(u=>u.seq)}}}function kIe(e,t){return t>=1||t>=.5?"high":t>=.25?e>=10?"high":"medium":e>=10?"medium":"low"}function TIe(e,t,n,r){let o=(r*100).toFixed(1);return`'${e}' tool failed ${t}/${n} calls (${o}%)`}function EIe(e){let t=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");return`tool-failure-${t.length>0?t:"unknown"}`}function RIe(e){return e.length<=2e3?e:e.slice(0,1997)+"..."}function xIe(e){return Math.round(e*1e4)/1e4}function AIe(e){return Math.round(e*100)/100}var ov=Object.freeze([{name:"repeated-tool-use",description:`Tool fired \u2265N consecutive times with identical fingerprint (default ${vo})`,run:(e,t)=>nv(e,{minRepeats:t.minRepeats??vo})},{name:"closure-anomaly",description:`Session closure reason \u2208 {budget_exceeded,timeout,hook_blocked,abort,iteration_cap,max_turns_exceeded} (default \u2265${1})`,enabledByDefault:!0,run:(e,t)=>rv(e,{minOccurrences:t.closureAnomalyMinOccurrences??1})},{name:"subagent-block",description:`Same SubagentStart hook block reason recurring across \u2265N events (default ${la})`,enabledByDefault:!1,run:(e,t)=>d5(e,{minOccurrences:t.subagentBlockMinOccurrences??la})},{name:"tool-failure-density",description:`Tool with \u2265N failures (isError: true) AND failure rate \u2265R (defaults: ${ua} failures, ${da} rate)`,enabledByDefault:!0,run:(e,t)=>Gc(e,{minFailures:t.toolFailureMinFailures??ua,minFailureRate:t.toolFailureMinRate??da})},{name:"subagent-read-denial",description:`Forked sub-agent read auto-denied (PreToolUse block, path outside granted read roots) recurring across \u2265N events (default ${ca})`,enabledByDefault:!1,run:(e,t)=>p5(e,{minOccurrences:t.subagentReadDenialMinOccurrences??ca})}]);function m5(e,t,n,r){let o=[];for(let i of ov){if(n!==void 0){if(!n.has(i.name))continue}else if(r!==!0&&i.enabledByDefault===!1)continue;let s=i.run(e,t);o.push(...s)}return o}function iv(){return ov.map(e=>e.name)}function f5(){return ov.filter(e=>e.enabledByDefault!==!1).map(e=>e.name)}function qc(){return ov.filter(e=>e.enabledByDefault===!1).map(e=>e.name)}import{existsSync as fm,mkdirSync as R5,readFileSync as qIe,readdirSync as x5,writeFileSync as zIe}from"fs";import{join as A5}from"path";import{z as L}from"zod";var Pi=L.enum(["repeated-tool-use","subagent-block","closure-anomaly","tool-failure-density","subagent-read-denial"]),sv=L.enum(["low","medium","high"]),CIe=L.enum(["open","deferred","resolved"]),g5=L.object({sessionId:L.string().min(1),tracePath:L.string().min(1),eventIndices:L.array(L.number().int().nonnegative()).min(1),excerpt:L.string().max(2e3),annotation:L.string().optional()}),av=L.object({at:L.string().datetime(),text:L.string()}),mm=L.object({schemaVersion:L.literal(1),slug:L.string().regex(/^[a-z0-9][a-z0-9-]*$/,"slug must be lowercase alphanumeric with hyphens"),title:L.string().min(1).max(200),pattern:Pi,severity:sv,status:CIe,firstSeen:L.string().datetime(),lastSeen:L.string().datetime(),occurrenceCount:L.number().int().nonnegative(),evidence:L.array(g5).min(1),detail:L.record(L.string(),L.unknown()),notes:L.array(av).default([])}),FMt=L.object({slug:L.string().regex(/^[a-z0-9][a-z0-9-]*$/),title:L.string().min(1).max(200),pattern:Pi,severity:sv,observedAt:L.string().datetime(),evidence:L.array(g5).min(1),detail:L.record(L.string(),L.unknown())}),h5=L.object({timestamp:L.string().datetime(),event:L.enum(["created","updated","merged-noop"]),slug:L.string(),pattern:Pi,occurrenceCount:L.number().int().nonnegative(),evidenceAdded:L.number().int().nonnegative()}),_Ie=L.enum(["prompt-defect","schema-too-strict","schema-too-loose","tool-output-shape","hook-overreach","retry-policy","timeout-too-low","cost-control","dispatcher-bug","detector-needs-tuning","unknown"]),IIe=L.enum(["safe","moderate","high","forbidden"]),PIe=L.enum(["low","medium","high"]),MIe=L.object({cardSlug:L.string(),eventIndices:L.array(L.number().int().nonnegative()).min(1),annotation:L.string().optional()}),OIe=L.object({path:L.string().min(1),rationale:L.string(),riskTier:IIe,confidence:PIe}),$Ie=L.object({unitTests:L.array(L.string()),evalCases:L.array(L.string()),smokeChecks:L.array(L.string()),manualChecks:L.array(L.string())}),DIe=L.object({forbiddenPaths:L.array(L.string()),requiresExplicitApproval:L.boolean()}),FIe=L.enum(["draft","approved","rejected","superseded"]),lI=L.object({schemaVersion:L.literal(1),proposalId:L.string().regex(/^[a-z0-9][a-z0-9-]*$/),cardSlug:L.string().regex(/^[a-z0-9][a-z0-9-]*$/),title:L.string().min(1).max(200),hypothesis:L.string().min(1),rootCauseClass:_Ie,evidenceRefs:L.array(MIe).min(1),fixSketch:L.string().min(1),likelyFiles:L.array(OIe),riskLevel:sv,validationPlan:$Ie,scopeFreeze:DIe,generatedBy:L.enum(["template","llm"]),createdAt:L.string().datetime(),status:FIe,notes:L.array(av).default([])}),y5=L.object({timestamp:L.string().datetime(),event:L.enum(["created","triaged","superseded"]),proposalId:L.string(),cardSlug:L.string(),generatedBy:L.enum(["template","llm"]),riskLevel:sv}),LIe=L.object({sourceSessionId:L.string().min(1),sourceTracePath:L.string().min(1),fixturePath:L.string().min(1),evidenceRowIndex:L.number().int().nonnegative(),evidenceEventIndices:L.array(L.number().int().nonnegative()).min(1),sliceLineRange:L.object({startLine:L.number().int().positive(),endLine:L.number().int().positive()}),sliceLineCount:L.number().int().positive(),sliceSha256:L.string().regex(/^[0-9a-f]{64}$/,"sliceSha256 must be 64 lowercase hex chars")}),NIe=L.object({kind:L.literal("pattern-absent"),patternId:Pi,detectorVersion:L.string().min(1),rationale:L.string().min(1)}),BIe=L.object({detectorAtGeneration:L.string().min(1),fingerprintAtGeneration:L.string().nullable(),cardOccurrenceCountAtGeneration:L.number().int().nonnegative(),cardLastSeenAtGeneration:L.string().datetime(),generatedBy:L.literal("replay-fixture")}),UIe=L.enum(["draft","approved","rejected","superseded"]),lv=L.object({schemaVersion:L.literal(1),evalCaseId:L.string().regex(/^[a-z0-9][a-z0-9-]*$/,"evalCaseId must be lowercase alphanumeric with hyphens"),cardSlug:L.string().regex(/^[a-z0-9][a-z0-9-]*$/),proposalId:L.string().regex(/^[a-z0-9][a-z0-9-]*$/).nullable(),title:L.string().min(1).max(200),createdAt:L.string().datetime(),kind:L.literal("replay"),replay:LIe,assertion:NIe,provenance:BIe,status:UIe,notes:L.array(av).default([])}),b5=L.object({timestamp:L.string().datetime(),event:L.enum(["created","triaged","superseded"]),evalCaseId:L.string(),cardSlug:L.string(),proposalId:L.string().nullable(),kind:L.literal("replay")}),jIe=L.enum(["pass","fail","skipped"]),HIe=L.object({name:L.string().min(1),description:L.string().min(1),status:jIe,expected:L.string(),actual:L.string()}),WIe=L.enum(["config-value","observed-behavior","source-symbol","fixture"]),KIe=L.object({kind:WIe,ref:L.string().min(1),detail:L.string()}),w5=L.enum(["pass","fail","unsupported","error"]),cI=L.object({schemaVersion:L.literal(1),evalRunId:L.string().regex(/^[a-z0-9][a-z0-9-]*$/,"evalRunId must be lowercase alphanumeric with hyphens"),evalCaseId:L.string().min(1),cardSlug:L.string().min(1),patternId:Pi,contract:L.string().min(1).nullable(),status:w5,createdAt:L.string().datetime(),durationMs:L.number().int().nonnegative(),checks:L.array(HIe),evidence:L.array(KIe),runner:L.object({version:L.string().min(1),mode:L.literal("deterministic")}),notes:L.array(av).default([])}),S5=L.object({timestamp:L.string().datetime(),event:L.literal("created"),evalRunId:L.string(),evalCaseId:L.string(),cardSlug:L.string(),patternId:Pi,contract:L.string().nullable(),status:w5}),v5=Object.freeze(["**/auth/**","**/billing/**","**/secrets/**","**/credentials*",".env",".env.*","pnpm-lock.yaml","package-lock.json","yarn.lock",".github/workflows/**","dist/**","build/**","node_modules/**",".git/**","**/.afk/config/**","**/.afk/state/**"]);var k5={low:0,medium:1,high:2};function GIe(e,t){return k5[e]>=k5[t]?e:t}function T5(e){let t=e?.detector;return typeof t=="string"&&t.length>0?t:void 0}function E5(e,t){let n=T5(e.detail),r=T5(t.detail);return n!==void 0&&r!==void 0&&n!==r?t.severity:GIe(e.severity,t.severity)}zr();function C5(e){let t=_i();fm(t)||R5(t,{recursive:!0});let n=dm(e.slug),r=tv(e.slug),o=zc(n),i=JIe(o,e),s=o===void 0,a=i.evidence.length-(o?.evidence.length??0),l=s?"created":a>0?"updated":"merged-noop",c=mm.parse(i);return Ze(n,JSON.stringify(c,null,2),438),Ze(r,gm(c),438),YIe({timestamp:XIe(),event:l,slug:c.slug,pattern:c.pattern,occurrenceCount:c.occurrenceCount,evidenceAdded:Math.max(0,a)}),{slug:c.slug,event:l,occurrenceCount:c.occurrenceCount,evidenceAdded:Math.max(0,a),jsonPath:n,markdownPath:r}}function zc(e){if(fm(e))try{let t=qIe(e,"utf-8"),n=JSON.parse(t),r=mm.safeParse(n);return r.success?r.data:void 0}catch{return}}function JIe(e,t){if(!e)return{schemaVersion:1,slug:t.slug,title:t.title,pattern:t.pattern,severity:t.severity,status:"open",firstSeen:t.observedAt,lastSeen:t.observedAt,occurrenceCount:t.evidence.length,evidence:t.evidence,detail:t.detail,notes:[]};if(e.slug!==t.slug)throw new Error(`card-writer: slug mismatch on merge (existing='${e.slug}', detection='${t.slug}')`);let n=VIe(e.evidence,t.evidence),r=QIe(e.firstSeen,t.observedAt),o=ZIe(e.lastSeen,t.observedAt),i=E5(e,t);return{schemaVersion:1,slug:e.slug,title:t.title,pattern:e.pattern,severity:i,status:e.status,firstSeen:r,lastSeen:o,occurrenceCount:n.length,evidence:n,detail:t.detail,notes:e.notes}}function VIe(e,t){let n=i=>`${i.sessionId}::${i.eventIndices[0]??"NA"}`,r=new Set(e.map(n)),o=[...e];for(let i of t){let s=n(i);r.has(s)||(r.add(s),o.push(i))}return o}function gm(e){let t=[];t.push(`# ${e.slug} \u2014 \`${e.severity}\` \u2014 \`${e.status}\``),t.push(""),t.push(e.title),t.push(""),t.push(`**Pattern:** \`${e.pattern}\` \xB7 **Occurrences:** ${e.occurrenceCount} \xB7 **First seen:** ${e.firstSeen} \xB7 **Last seen:** ${e.lastSeen}`),t.push(""),t.push("## Evidence"),t.push("");for(let n of e.evidence)t.push(`### Session \`${n.sessionId}\``),t.push(""),t.push(`- Trace: \`${n.tracePath}\``),t.push(`- Event seqs: ${n.eventIndices.join(", ")}`),n.annotation&&t.push(`- Note: ${n.annotation}`),t.push(""),t.push("```jsonl"),t.push(n.excerpt),t.push("```"),t.push("");if(t.push("## Detail"),t.push(""),t.push("```json"),t.push(JSON.stringify(e.detail,null,2)),t.push("```"),t.push(""),t.push("## Triage notes"),t.push(""),e.notes.length>0){for(let n of e.notes)t.push(`- _${n.at}_ \u2014 ${n.text}`);t.push("")}else t.push('_(none \u2014 add one with `afk improve cards triage <slug> --note "\u2026"`)_'),t.push("");return t.join(`
2068
+ `)}function YIe(e){let t=h5.parse(e),n=Z6(),r=_i();fm(r)||R5(r,{recursive:!0});try{zIe(n,JSON.stringify(t)+`
2069
+ `,{flag:"a"})}catch{}}function XIe(){return new Date().toISOString()}function QIe(e,t){return e<=t?e:t}function ZIe(e,t){return e>=t?e:t}function _5(){let e=_i();if(!fm(e))return[];let t=[];for(let n of x5(e)){if(!n.endsWith(".json")||n.startsWith("."))continue;let r=zc(A5(e,n));r&&t.push({slug:r.slug,title:r.title,pattern:r.pattern,severity:r.severity,status:r.status,occurrenceCount:r.occurrenceCount,firstSeen:r.firstSeen,lastSeen:r.lastSeen})}return t.sort((n,r)=>n.lastSeen!==r.lastSeen?n.lastSeen<r.lastSeen?1:-1:n.slug<r.slug?-1:1),t}function Jc(e){return zc(dm(e))}function I5(e){let t;for(let n of e.notes)(t===void 0||Date.parse(n.at)>Date.parse(t))&&(t=n.at);return t}function ePe(e){if(e.status!=="resolved"&&e.status!=="deferred")return!1;let t=I5(e);if(t===void 0)return!1;let n=Date.parse(e.lastSeen),r=Date.parse(t);return Number.isNaN(n)||Number.isNaN(r)?!1:n>r}function tPe(e){let t=[];for(let n of e){if(!ePe(n))continue;let r=I5(n);r!==void 0&&t.push({slug:n.slug,pattern:n.pattern,severity:n.severity,status:n.status,occurrenceCount:n.occurrenceCount,lastSeen:n.lastSeen,latestNoteAt:r})}return t.sort((n,r)=>n.lastSeen!==r.lastSeen?n.lastSeen<r.lastSeen?1:-1:n.slug<r.slug?-1:1),t}function P5(){let e=_i();if(!fm(e))return[];let t=[];for(let n of x5(e)){if(!n.endsWith(".json")||n.startsWith("."))continue;let r=zc(A5(e,n));r&&t.push(r)}return tPe(t)}function M5(e){e.command("scan").description(`Run registered detectors against witness traces. Dry-run by default.
2070
+ Some detectors are disabled by default (pass --include-disabled to enable): ${qc().join(", ")}.`).option("--since <duration>","Only scan sessions newer than this (e.g. 7d, 24h, all)","7d").option("--write","Persist failure cards to disk. Without this flag, scan is dry-run.",!1).option("--min-repeats <n>",`repeated-tool-use threshold (default ${vo})`,String(vo)).option("--closure-min-occurrences <n>",`closure-anomaly threshold (default ${1})`,String(1)).option("--block-min-occurrences <n>",`subagent-block threshold (default ${la})`,String(la)).option("--read-denial-min-occurrences <n>",`subagent-read-denial threshold (default ${ca})`,String(ca)).option("--tool-failure-min-failures <n>",`tool-failure-density absolute count threshold (default ${ua})`,String(ua)).option("--tool-failure-min-rate <rate>",`tool-failure-density rate threshold, 0\u20131 (default ${da})`,String(da)).option("--only <names>",`Comma-separated detector names to run (any of: ${iv().join(", ")})`).option("--include-disabled",`Run detectors marked disabled-by-default (currently: ${qc().join(", ")})`,!1).action(t=>{try{let n=hm(t.minRepeats,"min-repeats",2),r=hm(t.closureMinOccurrences,"closure-min-occurrences",1),o=hm(t.blockMinOccurrences,"block-min-occurrences",1),i=hm(t.readDenialMinOccurrences,"read-denial-min-occurrences",1),s=hm(t.toolFailureMinFailures,"tool-failure-min-failures",1),a=nPe(t.toolFailureMinRate,"tool-failure-min-rate"),l;if(t.only){let w=t.only.split(",").map(E=>E.trim()).filter(E=>E.length>0),k=new Set(iv()),S=w.filter(E=>!k.has(E));S.length>0&&(console.error(`Unknown detector(s): ${S.join(", ")}. Known: ${iv().join(", ")}`),process.exit(2)),l=new Set(w)}let c;if(t.since&&t.since!=="all"){let w=l5(t.since);w===void 0&&(console.error(`Invalid --since: '${t.since}'. Use forms like '7d', '24h', '30m', '3600s', or 'all'.`),process.exit(2)),c=Date.now()-w}let u=c5({sinceMs:c}),d={minRepeats:n,closureAnomalyMinOccurrences:r,subagentBlockMinOccurrences:o,subagentReadDenialMinOccurrences:i,toolFailureMinFailures:s,toolFailureMinRate:a},p=m5(u.sessions,d,l,t.includeDisabled);console.log(`Scanned ${u.sessionsScanned} sessions`),u.sessionsSkippedOld>0&&console.log(` \u21B3 skipped ${u.sessionsSkippedOld} older than --since`),u.sessionsSkippedEmpty>0&&console.log(` \u21B3 skipped ${u.sessionsSkippedEmpty} with missing/unreadable trace.jsonl`),u.invalidLineCount>0&&console.log(` \u26A0 ${u.invalidLineCount} invalid JSONL lines skipped`);let f=qc();!t.only&&!t.includeDisabled&&f.length>0&&console.log(`Skipped ${f.length} detectors (disabled by default \u2014 pass --only or --include-disabled): ${f.join(", ")}`);let g=new Map;for(let w of p)g.set(w.pattern,(g.get(w.pattern)??0)+1);console.log(`Detections: ${p.length}`);for(let[w,k]of g.entries())console.log(` \u21B3 ${w}: ${k}`);if(p.length===0){t.write&&console.log("No cards written.");return}for(let w of p)console.log(` \u2022 ${w.slug} [${w.severity}] ${w.pattern} evidence=${w.evidence.length}`);if(!t.write){console.log(""),console.log("(dry-run \u2014 pass --write to persist cards)");return}let h=0,y=0,b=0;for(let w of p){let k=C5(w);k.event==="created"?h+=1:k.event==="updated"?y+=1:b+=1}console.log(""),console.log(`Wrote cards: ${h} created, ${y} updated, ${b} no-op merges.`)}catch(n){J(n)}})}function hm(e,t,n){let r=Number.parseInt(e,10);return(!Number.isFinite(r)||r<n)&&(console.error(`Invalid --${t}: '${e}' (must be integer >= ${n})`),process.exit(2)),r}function nPe(e,t){let n=Number.parseFloat(e);return(!Number.isFinite(n)||n<=0||n>1)&&(console.error(`Invalid --${t}: '${e}' (must be number in (0, 1])`),process.exit(2)),n}import{existsSync as rPe,mkdirSync as oPe}from"fs";import{dirname as iPe}from"path";zr();var pa=class extends Error{constructor(n,r){super(r);this.code=n;this.name="TriageError"}code};function O5(e,t){let n=dm(e),r=tv(e),o=zc(n);if(!o)throw new pa("card-not-found",`No failure card found for slug '${e}'`);if(t.note!==void 0&&t.note.trim().length===0)throw new pa("invalid-note","triage note must be non-empty after trim");let i=t.note?.trim(),s=i!==void 0&&i.length>0,a=t.status!==void 0&&t.status!==o.status;if(!s&&!a)throw new pa("no-change","triage requires at least --note or --status to differ from current");let l=(t.now??(()=>new Date))().toISOString(),c=s?[...o.notes,{at:l,text:i}]:o.notes,u=a?t.status:o.status,d={...o,status:u,notes:c},p=mm.parse(d);return sPe(n),Ze(n,JSON.stringify(p,null,2),438),Ze(r,gm(p),438),{slug:e,card:p,noteAdded:s,statusChanged:a?{from:o.status,to:u}:void 0,jsonPath:n,markdownPath:r}}function sPe(e){let t=iPe(e);rPe(t)||oPe(t,{recursive:!0})}var uI=["open","deferred","resolved"];function aPe(e){let t=P5();if(e.pattern&&(t=t.filter(o=>o.pattern===e.pattern)),e.severity&&(t=t.filter(o=>o.severity===e.severity)),e.status&&(t=t.filter(o=>o.status===e.status)),e.json){console.log(JSON.stringify(t,null,2));return}if(t.length===0){console.log("No regressed cards found (no resolved/deferred card has fired since its latest triage note).");return}let n="SLUG | PATTERN | SEV | STATUS | N | LAST SEEN | LATEST NOTE",r="-".repeat(n.length);console.log(`${t.length} regressed card(s): triaged, then fired again afterwards.`),console.log(n),console.log(r);for(let o of t)console.log([o.slug.padEnd(50).slice(0,50),o.pattern.padEnd(20),o.severity.padEnd(6),o.status.padEnd(9),String(o.occurrenceCount).padEnd(4),o.lastSeen.padEnd(24),o.latestNoteAt].join(" | "))}function $5(e){let t=e.command("cards").description("Inspect and triage failure cards written by `afk improve scan`");t.command("list").description("List all failure cards, newest first").option("--pattern <name>","Filter by pattern name").option("--severity <level>","Filter by severity: low | medium | high").option("--status <state>","Filter by status: open | deferred | resolved").option("--regressed","Only show resolved/deferred cards that fired again after their latest triage note",!1).option("--json","Emit JSON instead of a table",!1).action(n=>{try{if(n.regressed){aPe(n);return}let r=_5();if(n.pattern&&(r=r.filter(s=>s.pattern===n.pattern)),n.severity&&(r=r.filter(s=>s.severity===n.severity)),n.status&&(r=r.filter(s=>s.status===n.status)),n.json){console.log(JSON.stringify(r,null,2));return}if(r.length===0){console.log("No failure cards found.");return}let o="SLUG | PATTERN | SEV | STATUS | N | LAST SEEN",i="-".repeat(o.length);console.log(o),console.log(i);for(let s of r)console.log([s.slug.padEnd(50).slice(0,50),s.pattern.padEnd(20),s.severity.padEnd(6),s.status.padEnd(9),String(s.occurrenceCount).padEnd(4),s.lastSeen].join(" | "))}catch(r){J(r)}}),t.command("show <slug>").description("Print a failure card by slug").option("--json","Emit raw JSON instead of rendered markdown",!1).action((n,r)=>{try{let o=Jc(n);if(o||(console.error(`Card not found: ${n}`),process.exit(1)),r.json){console.log(JSON.stringify(o,null,2));return}console.log(gm(o))}catch(o){J(o)}}),t.command("triage <slug>").description("Append a human note and/or change status on a failure card").option("--note <text>","Note text to append (non-empty)").option("--status <state>",`New status (one of: ${uI.join(", ")})`).option("--json","Emit the resulting card as JSON",!1).action((n,r)=>{try{let o;r.status!==void 0&&(uI.includes(r.status)||(console.error(`Invalid --status: '${r.status}'. Must be one of: ${uI.join(", ")}`),process.exit(2)),o=r.status);let i=O5(n,{...r.note!==void 0?{note:r.note}:{},...o!==void 0?{status:o}:{}});if(r.json){console.log(JSON.stringify(i.card,null,2));return}let s=[];i.noteAdded&&s.push("note appended"),i.statusChanged&&s.push(`status: ${i.statusChanged.from} \u2192 ${i.statusChanged.to}`),console.log(`Triaged ${n}: ${s.join(" \xB7 ")}`),console.log(` json: ${i.jsonPath}`),console.log(` md: ${i.markdownPath}`)}catch(o){o instanceof pa&&(console.error(`triage failed [${o.code}]: ${o.message}`),process.exit(o.code==="card-not-found"?1:2)),J(o)}})}var lPe={"repeated-tool-use":{rootCauseClass:"dispatcher-bug",hypothesis:e=>{let t=typeof e.detail.toolName=="string"?e.detail.toolName:"<unknown>",n=typeof e.detail.runLength=="number"?e.detail.runLength:"?";return`The '${t}' tool was dispatched ${n} times in a row with an identical input/output byte fingerprint. This is either (a) the model is stuck retrying the same call without responding to its result, (b) the tool's result shape is too uninformative for the model to make progress, or (c) a productive recursion that happens to share byte counts (rare; the fingerprint caveat is documented on the detector).`},fixSketch:e=>["## Candidate fixes (human picks)","",`**Option A \u2014 make the loop visible.** Surface a clear "no-progress" signal to the model when '${typeof e.detail.toolName=="string"?e.detail.toolName:"<the tool>"}' returns the same result N times in a row. Today the dispatcher just executes the call.`,"",`**Option B \u2014 improve the tool's result shape.** If the model can't distinguish "no results" from "same results," its result is information-poor. Inspect the tool's response and verify it carries enough signal for the model to change its query.`,"","**Option C \u2014 confirm productive recursion.** Open the source trace at the seq values listed in the evidence and inspect the model's reasoning between repeats. If each call's args genuinely differ (and the byte-count collision is the issue), no code change is needed; tune the detector instead.","","_Option C first \u2014 the byte-fingerprint detector has a documented collision caveat. Confirm there is a real loop before changing dispatcher behavior._"].join(`
2071
2071
  `),likelyFiles:[{path:"src/agent/providers/anthropic-direct/loop.ts",rationale:"Main tool dispatch loop. If a no-progress detector is added at the dispatch boundary, it lives here.",riskTier:"moderate",confidence:"medium"},{path:"src/agent/tools/",rationale:"Tool implementations. If the result shape is information-poor, the specific tool implementation needs the change.",riskTier:"safe",confidence:"low"},{path:"src/improve/scan/detectors/repeated-tool-use.ts",rationale:"If this turns out to be detector noise rather than a real bug, tune here.",riskTier:"safe",confidence:"medium"}],riskFloor:"medium",validationPlan:{unitTests:["pnpm test src/improve/scan/detectors/repeated-tool-use","pnpm test src/agent/providers/anthropic-direct"],evalCases:[],smokeChecks:["pnpm lint","afk improve scan --since 7d # after fix lands, this pattern should NOT recur"],manualChecks:["Open the trace at the evidence seqs and confirm the calls are truly identical (not just byte-coincident)."]}},"subagent-block":{rootCauseClass:"hook-overreach",hypothesis:e=>{let t=typeof e.detail.reason=="string"?e.detail.reason:"",n=typeof e.detail.blockCount=="number"?e.detail.blockCount:"?",r=typeof e.detail.distinctSessions=="number"?e.detail.distinctSessions:"?",o=t?` with reason "${t.slice(0,200)}"`:" (no reason field on the block events)";return`A SubagentStart hook returned decision:'block' ${n} times across ${r} session(s)${o}. Recurring blocks suggest either (a) the guard is over-broad and trips on legitimate dispatches, (b) the legitimate use case actually needs a refactor to satisfy the guard, or (c) the user has no signal explaining the block and keeps retrying.`},fixSketch:e=>{let t=typeof e.detail.reason=="string"?e.detail.reason:"<not in payload>";return["## Candidate fixes (human picks)","",`**Identify the hook owner first.** The trace's hook_decision event carries the \`reason\` field ("${t}"). Grep the codebase for that literal string \u2014 that locates the hook handler.`,"","```sh","# Replace the quoted string below with the actual reason text from the evidence.",`grep -rn -- "${t.slice(0,60).replace(/"/g,'\\"')}" src/`,"```","","**Option A \u2014 tighten the guard.** If the block fires on dispatches it should not, narrow the predicate. Confirm by adding a unit test that exercises the false-positive case.","","**Option B \u2014 make the refusal legible.** Instead of `decision: 'block'`, return a hook decision that injects a context message via `injectContext`. The parent session then sees a clear no-op message instead of a silent block.","",'**Option C \u2014 accept the block as correct.** If the guard is doing its job, mark the card resolved via `afk improve cards triage <slug> --status resolved --note "..."`. No code change.'].join(`
2072
2072
  `)},likelyFiles:[{path:"src/agent/hooks.ts",rationale:"Hook dispatch core. Only touched if the injectContext mechanism itself needs an extension.",riskTier:"high",confidence:"low"},{path:"src/agent/hook-registry.ts",rationale:"Hook registration. Same caveat \u2014 usually not the right spot.",riskTier:"high",confidence:"low"},{path:"src/agent/subagent-hooks.ts",rationale:"SubagentStart hook dispatch path. The reason text is set by whatever handler is registered here.",riskTier:"moderate",confidence:"medium"},{path:"src/skills/",rationale:"A skill is the typical owner of a SubagentStart hook. Grep for the block reason text to locate the specific handler.",riskTier:"safe",confidence:"medium"}],riskFloor:"medium",validationPlan:{unitTests:["pnpm test src/agent/hooks","pnpm test src/agent/subagent-hooks","pnpm test src/improve/scan/detectors/subagent-block"],evalCases:[],smokeChecks:["pnpm lint","afk improve scan --since 7d # after fix, blocks with same reason should not recur"],manualChecks:["Grep the codebase for the reason text from the evidence to find the hook handler.","Run a session that exercises the legitimate dispatch and confirm it is no longer blocked."]}},"subagent-read-denial":{rootCauseClass:"dispatcher-bug",hypothesis:e=>{let t=typeof e.detail.denialCount=="number"?e.detail.denialCount:"?",n=typeof e.detail.distinctSessions=="number"?e.detail.distinctSessions:"?";return`The path-approval PreToolUse hook auto-denied a forked sub-agent's READ (${Array.isArray(e.detail.blockedTools)?e.detail.blockedTools.join(", "):"?"}) ${t} times across ${n} session(s) \u2014 the resolved path fell outside the fork's granted READ roots and a fork cannot prompt to approve. The child then retries the read and spins until a wall-clock timeout. Root cause is almost always a read-scope grant that is NARROWER than the parent's: the fork was given a concrete cwd but not the parent's read reach (main repo, sibling .afk-worktrees/*, ~/.afk/state).`},fixSketch:()=>["## Candidate fixes (human picks)","","**Option A \u2014 widen the fork's inherited read scope (usual fix).** A forked read-only sub-agent must be able to READ everything its parent could; only WRITES stay confined. The inheritance rule lives in `computeInheritedReadRoots` (`src/agent/subagent-read-scope.ts`), applied at the fork choke point in `SubagentManager.forkSubagent` (`src/agent/subagent.ts`). Confirm an unconfined parent yields a read-open child and a confined parent yields union(childCwd, parentRoots, worktreeMainRoot).","","**Option B \u2014 verify the `afk farm` guardrail still holds.** A caller that pins `readRoots` (branch workers) must keep suppressing inheritance so a deliberately-confined worker is never widened. Guard with the regression test in `subagent-worktree-readroot.test.ts`.","","**Option C \u2014 fail fast instead of hanging.** If a denial is legitimate (genuinely out-of-scope), the fork should abort with an actionable message after N identical denials rather than retry to a wall-clock timeout. Separate hardening from the scope fix."].join(`
2073
2073
  `),likelyFiles:[{path:"src/agent/subagent-read-scope.ts",rationale:"The read-scope inheritance rule (computeInheritedReadRoots). The usual fix site.",riskTier:"moderate",confidence:"high"},{path:"src/agent/subagent.ts",rationale:"forkSubagent applies the inherited read roots at the fork choke point.",riskTier:"moderate",confidence:"medium"},{path:"src/agent/tools/hooks/path-approval-hook.ts",rationale:"The PreToolUse hook that auto-denies out-of-root reads. Touch only to change the fail-fast behavior (Option C), not the grant.",riskTier:"high",confidence:"low"}],riskFloor:"medium",validationPlan:{unitTests:["pnpm test src/agent/subagent-read-scope","pnpm test src/agent/subagent-worktree-readroot","pnpm test src/improve/scan/detectors/subagent-read-denial"],evalCases:[],smokeChecks:["pnpm lint","afk improve scan --only subagent-read-denial --since 7d # after fix, read-denials should not recur"],manualChecks:["Open the trace at the evidence seqs; confirm the denied paths are ones the parent could read (main repo / sibling worktree / ~/.afk/state).","Run a fan-out (e.g. /diagnose) that dispatches read-only forks and confirm they can read across the workspace."]}},"tool-failure-density":{rootCauseClass:"unknown",hypothesis:e=>{let t=typeof e.detail.toolName=="string"?e.detail.toolName:"<unknown>",n=typeof e.detail.failureCount=="number"?e.detail.failureCount:"?",r=typeof e.detail.totalCalls=="number"?e.detail.totalCalls:"?",o=typeof e.detail.failureRate=="number"?`${(e.detail.failureRate*100).toFixed(1)}%`:"?%",i=typeof e.detail.truncatedFailureCount=="number"?e.detail.truncatedFailureCount:0,s=i>0?` ${i} of those failures were also truncated, which often indicates a separate output-shape problem.`:"";return`The '${t}' tool returned isError: true on ${n}/${r} calls (${o}).${s} Likely causes: (a) the tool's handler has a bug, (b) the model is calling the tool with malformed inputs the tool rejects, (c) a permission/hook guard is denying legitimate calls, or (d) the tool legitimately returns isError as a signal to the model and this detector is firing on normal behavior.`},fixSketch:e=>{let t=typeof e.detail.toolName=="string"?e.detail.toolName:"<the tool>";return["## Diagnostic steps (do these first)","",`1. Inspect a representative failure trace: \`cat ~/.afk/state/witness/${(Array.isArray(e.detail.sessionIds)?e.detail.sessionIds:[])[0]??"<session-id>"}/trace.jsonl | grep '"name":"${t}"' | tail -5\``,"2. Look at the events immediately BEFORE each failure \u2014 what did the model send as input?","3. The witness trace does not capture tool args verbatim. To see the actual input, check the session message history under `~/.afk/state/sessions/<sessionId>/`.","","## Candidate fixes (human picks)","","**Option A \u2014 handler bug.** Locate the tool implementation under `src/agent/tools/handlers/` and read its error paths. If a specific failure mode is reachable from common LLM inputs, fix the handler.","","**Option B \u2014 input shape too restrictive.** If the tool's input schema rejects inputs the model naturally produces, either loosen the schema or improve the schema's description so the model can comply.","","**Option C \u2014 permission/hook denial.** Check whether a PreToolUse hook or permission gate is rejecting the call. The dispatcher returns isError: true for hook blocks and permission denials (`src/agent/tools/dispatcher.ts:337\u2013352`).","","**Option D \u2014 accept as normal.** Some tools intentionally return isError as a signal (e.g., grep finding nothing). If this is the case, mark the card resolved with a note explaining why, or tune the detector threshold via `--tool-failure-min-rate`."].join(`
2074
2074
  `)},likelyFiles:[{path:"src/agent/tools/dispatcher.ts",rationale:"Tool dispatch core. Every isError: true path goes through here: hook block, permission denied, handler throw, unknown tool. Read this to understand which class each failure falls into.",riskTier:"high",confidence:"medium"},{path:"src/agent/tools/handlers/",rationale:"Tool handlers. If a specific handler is buggy, the fix lives in the handler file matching the tool name (e.g. handlers/bash.ts for the Bash tool).",riskTier:"moderate",confidence:"medium"},{path:"src/improve/scan/detectors/tool-failure-density.ts",rationale:"If the detector is flagging legitimate isError-as-signal behavior, tune the threshold here or document the tool as expected-failures.",riskTier:"safe",confidence:"low"}],riskFloor:"medium",validationPlan:{unitTests:["pnpm test src/improve/scan/detectors/tool-failure-density","pnpm test src/agent/tools/dispatcher"],evalCases:[],smokeChecks:["pnpm lint","afk improve scan --only tool-failure-density --since 7d # after fix, failure rate should drop"],manualChecks:["Open the trace at the evidence seqs and read the failure annotations (resultBytes, durationMs).","Inspect the session message history for the actual tool input that triggered the failure.","Decide which of the four root cause classes (handler bug / input shape / permission / detector noise) the failures belong to."]}},"closure-anomaly":{rootCauseClass:"unknown",hypothesis:e=>{let t=typeof e.detail.closureReason=="string"?e.detail.closureReason:"<unknown>",n=typeof e.detail.affectedSessions=="number"?e.detail.affectedSessions:"?",r=typeof e.detail.totalCostUsd=="number"?e.detail.totalCostUsd:null,o=r!==null?` totalling $${r.toFixed(4)}`:"";return`${n} session(s) closed with reason='${t}'${o}. Anomalous closure reasons signal one of: budget mis-configuration, timeout too tight, a hook returning block at the session edge, or an explicit/cascaded abort. The right fix depends on the reason value.`},fixSketch:e=>{let t=typeof e.detail.closureReason=="string"?e.detail.closureReason:"<unknown>",r=(Array.isArray(e.detail.sessionIds)?e.detail.sessionIds:[])[0]??"<session-id>",o=cPe(t);return[`## Closure reason: \`${t}\``,"",o,"","## Diagnostic steps","",`1. Inspect the trace for one of the affected sessions: \`cat ~/.afk/state/witness/${r}/trace.jsonl | tail -20\``,"2. Check the events immediately before the closure \u2014 what was the runtime trying to do?","3. Cross-reference with `~/.afk/agent-framework/routing-decisions.jsonl` for any subagent activity at the same timestamp."].join(`
2075
- `)},likelyFiles:[{path:"src/agent/session/agent-session.ts",rationale:"Closure-event emission lives here. Field meanings and the reason classification are owned by this module.",riskTier:"high",confidence:"medium"},{path:"src/agent/session/stream-consumer.ts",rationale:"Budget threshold detection / closure-reason routing. Touch only if the closure CAUSE is here.",riskTier:"high",confidence:"low"},{path:"src/agent/abort-graph.ts",rationale:"Origin tracking for abort-type closures.",riskTier:"moderate",confidence:"low"}],riskFloor:"medium",validationPlan:{unitTests:["pnpm test src/agent/session","pnpm test src/improve/scan/detectors/closure-anomaly"],evalCases:[],smokeChecks:["pnpm lint"],manualChecks:["Read the closure events at the seqs listed in the evidence.","Confirm the closure reason is correct semantically (not a misclassification)."]}}};function cPe(e){switch(e){case"budget_exceeded":return"The monetary ceiling tripped. Confirm `AFK_MAX_BUDGET_USD` is set to a realistic value for the workload; if so, the LLM call shape (cache use, output cap, model choice) is the next place to look.";case"timeout":return"The wall-clock cap fired. Check whether the timeout is configured too tightly for the workload, or whether a tool call is hanging. Tool-call durations in the same trace will tell you which.";case"hook_blocked":return"A hook returned `decision: 'block'` at the session edge. Cross-reference with any `subagent-block` cards on this scan \u2014 the underlying cause is likely the same handler.";case"abort":return"An explicit or cascaded abort closed the session. If origin is `user_signal`, no action needed. If `cascade`/`budget`/`timeout`, the originating cause is the real issue.";case"iteration_cap":return"Loop iteration ceiling tripped. The model could not make progress in N turns. Either the task is genuinely impossible at that budget, or a tool is in an unproductive loop (cross-reference repeated-tool-use cards).";case"max_turns_exceeded":return"Turn ceiling tripped. Same diagnostic as iteration_cap.";default:return"Reason not in the known anomalous set. Inspect the trace and update the detector if this is a new closure variant."}}function F6(e,t){let n=lPe[e.pattern];if(!n)throw new Error(`template-engine: no template for pattern '${e.pattern}' \u2014 add one to TEMPLATES`);let r=(t.now??(()=>new Date))().toISOString(),o=n.hypothesis(e),i=n.fixSketch(e),s=n.likelyFiles.map(c=>({...c})),a=uPe(n.riskFloor,s),l=e.evidence.map(c=>({cardSlug:e.slug,eventIndices:[...c.eventIndices],...c.annotation!==void 0?{annotation:c.annotation}:{}}));return{schemaVersion:1,proposalId:t.proposalId,cardSlug:e.slug,title:mPe(e),hypothesis:o,rootCauseClass:n.rootCauseClass,evidenceRefs:l,fixSketch:i,likelyFiles:s,riskLevel:a,validationPlan:fPe(n.validationPlan),scopeFreeze:{forbiddenPaths:[...v6],requiresExplicitApproval:a==="high"},generatedBy:"template",createdAt:r,status:"draft",notes:[]}}function uPe(e,t){let n=dPe(t);return n==="forbidden"||n==="high"?"high":n==="moderate"?pPe(e,"medium"):e}function dPe(e){let t=["safe","moderate","high","forbidden"],n=0;for(let r of e){let o=t.indexOf(r.riskTier);o>n&&(n=o)}return t[n]}var D6={low:0,medium:1,high:2};function pPe(e,t){return D6[e]>=D6[t]?e:t}function mPe(e){return`Proposal: address ${e.pattern} \u2014 ${e.title}`.slice(0,200)}function fPe(e){return{unitTests:[...e.unitTests],evalCases:[...e.evalCases],smokeChecks:[...e.smokeChecks],manualChecks:[...e.manualChecks]}}import{randomBytes as gPe}from"crypto";import{existsSync as cv,mkdirSync as L6,readFileSync as hPe,readdirSync as yPe,writeFileSync as bPe}from"fs";import{join as wPe}from"path";zr();function N6(e){let t=lI.parse(e),n=aa();cv(n)||L6(n,{recursive:!0});let r=oI(t.proposalId),o=n6(t.proposalId);return Ze(r,JSON.stringify(t,null,2),438),Ze(o,uv(t),438),vPe({timestamp:new Date().toISOString(),event:"created",proposalId:t.proposalId,cardSlug:t.cardSlug,generatedBy:t.generatedBy,riskLevel:t.riskLevel}),{proposalId:t.proposalId,jsonPath:r,markdownPath:o}}function B6(e,t={}){let n=(t.now??(()=>new Date))(),r=SPe(n),o=t.randomSuffix!==void 0?t.randomSuffix():gPe(3).toString("hex");if(!/^[0-9a-f]{6}$/.test(o))throw new Error(`generateProposalId: randomSuffix must be 6 lowercase hex chars (got '${o}')`);return`${e}-${r}-${o}`}function SPe(e){let t=e.getUTCFullYear(),n=String(e.getUTCMonth()+1).padStart(2,"0"),r=String(e.getUTCDate()).padStart(2,"0");return`${t}${n}${r}`}function uv(e){let t=[];if(t.push(`# ${e.proposalId} \u2014 \`${e.riskLevel}\` \u2014 \`${e.status}\``),t.push(""),t.push(e.title),t.push(""),t.push(`**Card:** \`${e.cardSlug}\` \xB7 **Root cause class:** \`${e.rootCauseClass}\` \xB7 **Generated by:** \`${e.generatedBy}\` \xB7 **Created:** ${e.createdAt}`),t.push(""),t.push("## Hypothesis"),t.push(""),t.push(e.hypothesis),t.push(""),t.push(e.fixSketch),t.push(""),t.push("## Likely files"),t.push(""),e.likelyFiles.length===0)t.push("_(none suggested by the template)_");else{t.push("| Path | Risk | Confidence | Rationale |"),t.push("| --- | --- | --- | --- |");for(let n of e.likelyFiles){let r=n.path.replace(/\|/g,"\\|"),o=n.rationale.replace(/\n/g," ").replace(/\|/g,"\\|");t.push(`| \`${r}\` | ${n.riskTier} | ${n.confidence} | ${o} |`)}}t.push(""),t.push("## Evidence references"),t.push("");for(let n of e.evidenceRefs)t.push(`- card \`${n.cardSlug}\` \xB7 seqs ${n.eventIndices.join(", ")}${n.annotation?` \xB7 ${n.annotation}`:""}`);t.push(""),t.push("## Validation plan"),t.push(""),t.push("**Unit tests:**"),e.validationPlan.unitTests.length===0&&t.push("- _(none)_");for(let n of e.validationPlan.unitTests)t.push(`- \`${n}\``);if(t.push(""),t.push("**Eval cases:**"),e.validationPlan.evalCases.length===0)t.push(`- _(none \u2014 generate one with \`afk improve eval-gen ${e.cardSlug}\`)_`);else for(let n of e.validationPlan.evalCases)t.push(`- ${n}`);t.push(""),t.push("**Smoke checks:**"),e.validationPlan.smokeChecks.length===0&&t.push("- _(none)_");for(let n of e.validationPlan.smokeChecks)t.push(`- \`${n}\``);t.push(""),t.push("**Manual checks:**"),e.validationPlan.manualChecks.length===0&&t.push("- _(none)_");for(let n of e.validationPlan.manualChecks)t.push(`- ${n}`);t.push(""),t.push("## Scope freeze"),t.push(""),t.push(`**Requires explicit approval:** ${e.scopeFreeze.requiresExplicitApproval?"**yes**":"no"}`),t.push(""),t.push("**Forbidden paths** (never auto-edited by a future `apply`):");for(let n of e.scopeFreeze.forbiddenPaths)t.push(`- \`${n}\``);if(t.push(""),t.push("## Triage notes"),t.push(""),e.notes.length===0)t.push("_(none)_");else for(let n of e.notes)t.push(`- _${n.at}_ \u2014 ${n.text}`);return t.push(""),t.join(`
2076
- `)}function dI(){let e=aa();if(!cv(e))return[];let t=[];for(let n of yPe(e)){if(!n.endsWith(".json")||n.startsWith("."))continue;let r=j6(wPe(e,n));r&&t.push({proposalId:r.proposalId,cardSlug:r.cardSlug,title:r.title,riskLevel:r.riskLevel,status:r.status,rootCauseClass:r.rootCauseClass,generatedBy:r.generatedBy,createdAt:r.createdAt})}return t.sort((n,r)=>n.createdAt!==r.createdAt?n.createdAt<r.createdAt?1:-1:n.proposalId<r.proposalId?-1:1),t}function ym(e){return j6(oI(e))}function U6(e){return dI().filter(t=>t.cardSlug===e).map(t=>ym(t.proposalId)).filter(t=>t!==void 0)}function j6(e){if(cv(e))try{let t=hPe(e,"utf-8"),n=JSON.parse(t),r=lI.safeParse(n);return r.success?r.data:void 0}catch{return}}function vPe(e){let t=y6.parse(e),n=t6(),r=aa();cv(r)||L6(r,{recursive:!0});try{bPe(n,JSON.stringify(t)+`
2077
- `,{flag:"a"})}catch{}}function H6(e){e.command("propose <slug>").description("Generate a template-mode improvement proposal for a failure card. No LLM calls.").option("--id <override>","Override the auto-generated proposal id").option("--json","Emit the proposal JSON to stdout (still writes to disk)",!1).option("--no-write","Render the proposal without persisting to disk (preview mode)").option("--force","Write even if this card already has a proposal (default: refuse)",!1).action((t,n)=>{try{let r=Jc(t);if(r||(console.error(`Card not found: ${t}`),process.exit(1)),n.write!==!1&&!n.force){let a=U6(t);if(a.length>0){let l=a.map(c=>c.proposalId);console.error(`Card '${t}' already has ${a.length} proposal(s):
2075
+ `)},likelyFiles:[{path:"src/agent/session/agent-session.ts",rationale:"Closure-event emission lives here. Field meanings and the reason classification are owned by this module.",riskTier:"high",confidence:"medium"},{path:"src/agent/session/stream-consumer.ts",rationale:"Budget threshold detection / closure-reason routing. Touch only if the closure CAUSE is here.",riskTier:"high",confidence:"low"},{path:"src/agent/abort-graph.ts",rationale:"Origin tracking for abort-type closures.",riskTier:"moderate",confidence:"low"}],riskFloor:"medium",validationPlan:{unitTests:["pnpm test src/agent/session","pnpm test src/improve/scan/detectors/closure-anomaly"],evalCases:[],smokeChecks:["pnpm lint"],manualChecks:["Read the closure events at the seqs listed in the evidence.","Confirm the closure reason is correct semantically (not a misclassification)."]}}};function cPe(e){switch(e){case"budget_exceeded":return"The monetary ceiling tripped. Confirm `AFK_MAX_BUDGET_USD` is set to a realistic value for the workload; if so, the LLM call shape (cache use, output cap, model choice) is the next place to look.";case"timeout":return"The wall-clock cap fired. Check whether the timeout is configured too tightly for the workload, or whether a tool call is hanging. Tool-call durations in the same trace will tell you which.";case"hook_blocked":return"A hook returned `decision: 'block'` at the session edge. Cross-reference with any `subagent-block` cards on this scan \u2014 the underlying cause is likely the same handler.";case"abort":return"An explicit or cascaded abort closed the session. If origin is `user_signal`, no action needed. If `cascade`/`budget`/`timeout`, the originating cause is the real issue.";case"iteration_cap":return"Loop iteration ceiling tripped. The model could not make progress in N turns. Either the task is genuinely impossible at that budget, or a tool is in an unproductive loop (cross-reference repeated-tool-use cards).";case"max_turns_exceeded":return"Turn ceiling tripped. Same diagnostic as iteration_cap.";default:return"Reason not in the known anomalous set. Inspect the trace and update the detector if this is a new closure variant."}}function F5(e,t){let n=lPe[e.pattern];if(!n)throw new Error(`template-engine: no template for pattern '${e.pattern}' \u2014 add one to TEMPLATES`);let r=(t.now??(()=>new Date))().toISOString(),o=n.hypothesis(e),i=n.fixSketch(e),s=n.likelyFiles.map(c=>({...c})),a=uPe(n.riskFloor,s),l=e.evidence.map(c=>({cardSlug:e.slug,eventIndices:[...c.eventIndices],...c.annotation!==void 0?{annotation:c.annotation}:{}}));return{schemaVersion:1,proposalId:t.proposalId,cardSlug:e.slug,title:mPe(e),hypothesis:o,rootCauseClass:n.rootCauseClass,evidenceRefs:l,fixSketch:i,likelyFiles:s,riskLevel:a,validationPlan:fPe(n.validationPlan),scopeFreeze:{forbiddenPaths:[...v5],requiresExplicitApproval:a==="high"},generatedBy:"template",createdAt:r,status:"draft",notes:[]}}function uPe(e,t){let n=dPe(t);return n==="forbidden"||n==="high"?"high":n==="moderate"?pPe(e,"medium"):e}function dPe(e){let t=["safe","moderate","high","forbidden"],n=0;for(let r of e){let o=t.indexOf(r.riskTier);o>n&&(n=o)}return t[n]}var D5={low:0,medium:1,high:2};function pPe(e,t){return D5[e]>=D5[t]?e:t}function mPe(e){return`Proposal: address ${e.pattern} \u2014 ${e.title}`.slice(0,200)}function fPe(e){return{unitTests:[...e.unitTests],evalCases:[...e.evalCases],smokeChecks:[...e.smokeChecks],manualChecks:[...e.manualChecks]}}import{randomBytes as gPe}from"crypto";import{existsSync as cv,mkdirSync as L5,readFileSync as hPe,readdirSync as yPe,writeFileSync as bPe}from"fs";import{join as wPe}from"path";zr();function N5(e){let t=lI.parse(e),n=aa();cv(n)||L5(n,{recursive:!0});let r=oI(t.proposalId),o=n5(t.proposalId);return Ze(r,JSON.stringify(t,null,2),438),Ze(o,uv(t),438),vPe({timestamp:new Date().toISOString(),event:"created",proposalId:t.proposalId,cardSlug:t.cardSlug,generatedBy:t.generatedBy,riskLevel:t.riskLevel}),{proposalId:t.proposalId,jsonPath:r,markdownPath:o}}function B5(e,t={}){let n=(t.now??(()=>new Date))(),r=SPe(n),o=t.randomSuffix!==void 0?t.randomSuffix():gPe(3).toString("hex");if(!/^[0-9a-f]{6}$/.test(o))throw new Error(`generateProposalId: randomSuffix must be 6 lowercase hex chars (got '${o}')`);return`${e}-${r}-${o}`}function SPe(e){let t=e.getUTCFullYear(),n=String(e.getUTCMonth()+1).padStart(2,"0"),r=String(e.getUTCDate()).padStart(2,"0");return`${t}${n}${r}`}function uv(e){let t=[];if(t.push(`# ${e.proposalId} \u2014 \`${e.riskLevel}\` \u2014 \`${e.status}\``),t.push(""),t.push(e.title),t.push(""),t.push(`**Card:** \`${e.cardSlug}\` \xB7 **Root cause class:** \`${e.rootCauseClass}\` \xB7 **Generated by:** \`${e.generatedBy}\` \xB7 **Created:** ${e.createdAt}`),t.push(""),t.push("## Hypothesis"),t.push(""),t.push(e.hypothesis),t.push(""),t.push(e.fixSketch),t.push(""),t.push("## Likely files"),t.push(""),e.likelyFiles.length===0)t.push("_(none suggested by the template)_");else{t.push("| Path | Risk | Confidence | Rationale |"),t.push("| --- | --- | --- | --- |");for(let n of e.likelyFiles){let r=n.path.replace(/\|/g,"\\|"),o=n.rationale.replace(/\n/g," ").replace(/\|/g,"\\|");t.push(`| \`${r}\` | ${n.riskTier} | ${n.confidence} | ${o} |`)}}t.push(""),t.push("## Evidence references"),t.push("");for(let n of e.evidenceRefs)t.push(`- card \`${n.cardSlug}\` \xB7 seqs ${n.eventIndices.join(", ")}${n.annotation?` \xB7 ${n.annotation}`:""}`);t.push(""),t.push("## Validation plan"),t.push(""),t.push("**Unit tests:**"),e.validationPlan.unitTests.length===0&&t.push("- _(none)_");for(let n of e.validationPlan.unitTests)t.push(`- \`${n}\``);if(t.push(""),t.push("**Eval cases:**"),e.validationPlan.evalCases.length===0)t.push(`- _(none \u2014 generate one with \`afk improve eval-gen ${e.cardSlug}\`)_`);else for(let n of e.validationPlan.evalCases)t.push(`- ${n}`);t.push(""),t.push("**Smoke checks:**"),e.validationPlan.smokeChecks.length===0&&t.push("- _(none)_");for(let n of e.validationPlan.smokeChecks)t.push(`- \`${n}\``);t.push(""),t.push("**Manual checks:**"),e.validationPlan.manualChecks.length===0&&t.push("- _(none)_");for(let n of e.validationPlan.manualChecks)t.push(`- ${n}`);t.push(""),t.push("## Scope freeze"),t.push(""),t.push(`**Requires explicit approval:** ${e.scopeFreeze.requiresExplicitApproval?"**yes**":"no"}`),t.push(""),t.push("**Forbidden paths** (never auto-edited by a future `apply`):");for(let n of e.scopeFreeze.forbiddenPaths)t.push(`- \`${n}\``);if(t.push(""),t.push("## Triage notes"),t.push(""),e.notes.length===0)t.push("_(none)_");else for(let n of e.notes)t.push(`- _${n.at}_ \u2014 ${n.text}`);return t.push(""),t.join(`
2076
+ `)}function dI(){let e=aa();if(!cv(e))return[];let t=[];for(let n of yPe(e)){if(!n.endsWith(".json")||n.startsWith("."))continue;let r=j5(wPe(e,n));r&&t.push({proposalId:r.proposalId,cardSlug:r.cardSlug,title:r.title,riskLevel:r.riskLevel,status:r.status,rootCauseClass:r.rootCauseClass,generatedBy:r.generatedBy,createdAt:r.createdAt})}return t.sort((n,r)=>n.createdAt!==r.createdAt?n.createdAt<r.createdAt?1:-1:n.proposalId<r.proposalId?-1:1),t}function ym(e){return j5(oI(e))}function U5(e){return dI().filter(t=>t.cardSlug===e).map(t=>ym(t.proposalId)).filter(t=>t!==void 0)}function j5(e){if(cv(e))try{let t=hPe(e,"utf-8"),n=JSON.parse(t),r=lI.safeParse(n);return r.success?r.data:void 0}catch{return}}function vPe(e){let t=y5.parse(e),n=t5(),r=aa();cv(r)||L5(r,{recursive:!0});try{bPe(n,JSON.stringify(t)+`
2077
+ `,{flag:"a"})}catch{}}function H5(e){e.command("propose <slug>").description("Generate a template-mode improvement proposal for a failure card. No LLM calls.").option("--id <override>","Override the auto-generated proposal id").option("--json","Emit the proposal JSON to stdout (still writes to disk)",!1).option("--no-write","Render the proposal without persisting to disk (preview mode)").option("--force","Write even if this card already has a proposal (default: refuse)",!1).action((t,n)=>{try{let r=Jc(t);if(r||(console.error(`Card not found: ${t}`),process.exit(1)),n.write!==!1&&!n.force){let a=U5(t);if(a.length>0){let l=a.map(c=>c.proposalId);console.error(`Card '${t}' already has ${a.length} proposal(s):
2078
2078
  `+l.map(c=>` ${c}`).join(`
2079
2079
  `)+`
2080
- Re-run with --force to add another, --no-write to preview, or inspect with 'afk improve proposals show ${l[0]}'.`),process.exit(1)}}let o=n.id??B6(t),i=F6(r,{proposalId:o});if(n.write===!1){n.json?console.log(JSON.stringify(i,null,2)):(console.log("(preview \u2014 not persisted; remove --no-write to save)"),console.log(""),console.log(uv(i)));return}let s=N6(i);if(n.json){console.log(JSON.stringify({...i,_paths:s},null,2));return}console.log(`Wrote proposal: ${s.proposalId}`),console.log(` json: ${s.jsonPath}`),console.log(` md: ${s.markdownPath}`),console.log(` risk: ${i.riskLevel} \xB7 root cause: ${i.rootCauseClass} \xB7 approval required: ${i.scopeFreeze.requiresExplicitApproval?"yes":"no"}`)}catch(r){J(r)}})}function W6(e){let t=e.command("proposals").description("Inspect improvement proposals on disk");t.command("list").description("List all proposals, newest first").option("--card <slug>","Filter by card slug").option("--risk <level>","Filter by risk: low | medium | high").option("--json","Emit JSON instead of a table",!1).action(n=>{try{let r=dI();if(n.card&&(r=r.filter(s=>s.cardSlug===n.card)),n.risk&&(r=r.filter(s=>s.riskLevel===n.risk)),n.json){console.log(JSON.stringify(r,null,2));return}if(r.length===0){console.log("No proposals found.");return}let o="PROPOSAL ID | CARD | RISK | STATUS | CREATED",i="-".repeat(o.length);console.log(o),console.log(i);for(let s of r)console.log([s.proposalId.padEnd(64).slice(0,64),s.cardSlug.padEnd(44).slice(0,44),s.riskLevel.padEnd(6),s.status.padEnd(9),s.createdAt].join(" | "))}catch(r){J(r)}}),t.command("show <id>").description("Print a proposal by id").option("--json","Emit raw JSON instead of rendered markdown",!1).action((n,r)=>{try{let o=ym(n);if(o||(console.error(`Proposal not found: ${n}`),process.exit(1)),r.json){console.log(JSON.stringify(o,null,2));return}console.log(uv(o))}catch(o){J(o)}})}import{createHash as K6}from"crypto";import{existsSync as kPe,readFileSync as TPe}from"fs";var Mn=class extends Error{code;constructor(t,n){super(t),this.name="EvalGenError",this.code=n}};function G6(e,t){if(!kPe(e))throw new Mn(`replay-fixture: source trace not found: ${e}`,"source-not-found");let n=t.startLine??1;if(n!==1)throw new Mn(`replay-fixture: only startLine=1 (prefix slice) is supported in Sprint 3 (got ${n})`,"unsupported-window");let r=TPe(e);if(r.length===0)throw new Mn(`replay-fixture: source trace is empty: ${e}`,"source-empty");let o=EPe(r),i=o.length,s=-1;for(let d=0;d<o.length;d++){let p=o[d];if(p.contentEnd===p.start)continue;let f=r.subarray(p.start,p.contentEnd).toString("utf8"),g;try{g=JSON.parse(f)}catch{continue}if(g!==null&&typeof g=="object"&&"seq"in g&&typeof g.seq=="number"&&g.seq===t.endSeq){s=d+1;break}}if(s===-1)throw new Mn(`replay-fixture: seq ${t.endSeq} not found in ${e} (scanned ${i} lines)`,"seq-not-found");let l=o[s-1].byteEnd,c=Buffer.from(r.subarray(0,l)),u=K6("sha256").update(c).digest("hex");return{bytes:c,startLine:1,endLine:s,sliceLineCount:s,sliceSha256:u,sourceLineCount:i}}function dv(e){return K6("sha256").update(e).digest("hex")}function EPe(e){let t=[],n=0;for(let r=0;r<e.length;r++)e[r]===10&&(t.push({start:n,contentEnd:r,byteEnd:r+1}),n=r+1);return n<e.length&&t.push({start:n,contentEnd:e.length,byteEnd:e.length}),t}import{randomBytes as WPe}from"crypto";import{existsSync as yv,mkdirSync as n3,readFileSync as r3,readdirSync as KPe,renameSync as GPe,writeFileSync as o3}from"fs";import{join as i3,relative as qPe}from"path";G();zr();ja();_d();Ky();var q6=400;function cn(e){let n=(typeof e=="string"?e:String(e)).replace(/\s+/g," ").trim();return n.length>q6?n.slice(0,q6-1)+"\u2026":n}function _e(e){return{name:e.name,description:e.description,status:e.status??(e.pass?"pass":"fail"),expected:cn(e.expected),actual:cn(e.actual)}}var bm="eval_run_probe_tool";async function RPe(){let e=Ua,t=0,n=async()=>(t+=1,{content:"probe-ok"}),r=new Ft({handlers:new Map([[bm,n]]),schemas:[],hookRegistry:void 0,permissions:{allowedTools:[bm]}}),o=new AbortController().signal,i=h=>({id:"eval-run-probe",name:bm,input:h,signal:o}),s={probe:"byte-identical-input"},a=[];for(let h=0;h<e-1;h++)a.push(await r.execute(i(s)));let l=t,c=await r.execute(i(s)),u=t,d=await r.execute(i({probe:"a-different-input"})),p=a.every(h=>h.isError!==!0&&h.circuitBreaker!==!0),f=[_e({name:"executes-below-threshold",description:`First ${e-1} byte-identical calls execute without tripping`,pass:p&&l===e-1,expected:`${e-1} clean executions; handler runs ${e-1}\xD7`,actual:`${a.filter(h=>h.isError!==!0).length} clean; handler ran ${l}\xD7`}),_e({name:"trips-at-threshold",description:`Call #${e} is short-circuited with isError + circuitBreaker, handler skipped`,pass:c.isError===!0&&c.circuitBreaker===!0&&u===l,expected:"isError=true, circuitBreaker=true, handler not re-run",actual:`isError=${c.isError??!1}, circuitBreaker=${c.circuitBreaker??!1}, handler ran ${u}\xD7`}),_e({name:"breaker-message-is-actionable",description:"The synthetic block names the looping tool and reads as a stop nudge",pass:/circuit breaker/i.test(c.content)&&c.content.includes(bm),expected:`mentions "circuit breaker" and the tool name "${bm}"`,actual:c.content}),_e({name:"resets-on-different-input",description:"A different-input call after a trip resets the consecutive counter and executes",pass:d.isError!==!0&&d.circuitBreaker!==!0&&t===u+1,expected:"executes (no breaker), handler runs once more",actual:`isError=${d.isError??!1}, circuitBreaker=${d.circuitBreaker??!1}, handler ran ${t}\xD7`})],g=[{kind:"config-value",ref:"src/agent/tools/dispatcher.ts#REPEAT_CIRCUIT_BREAKER_THRESHOLD",detail:String(e)},{kind:"observed-behavior",ref:"SessionToolDispatcher.execute",detail:`handler ran ${u}\xD7 across ${e} byte-identical calls; call #${e} short-circuited (circuitBreaker=${c.circuitBreaker??!1})`}];return{checks:f,evidence:g}}async function xPe(){let n=Bh(3,3);return{checks:[_e({name:"refusal-states-depth",description:"Refusal reports the depth that was hit and the max",pass:n.includes("nesting depth 3 (max 3)"),expected:'mentions "nesting depth 3 (max 3)"',actual:n}),_e({name:"recovery-hint-present",description:"Refusal carries the recovery hint clause",pass:n.includes(Vo),expected:"contains SKILL_MAX_DEPTH_RECOVERY_HINT",actual:n}),_e({name:"hint-directs-inline-work",description:"Hint tells the model to work inline instead of delegating further",pass:/perform the work inline/i.test(Vo)&&/skill\/agent\/compose/i.test(Vo),expected:'hint mentions "perform the work inline" and "skill/agent/compose"',actual:Vo})],evidence:[{kind:"source-symbol",ref:"src/agent/tools/skill-depth-message.ts#buildSkillMaxDepthRefusal",detail:n},{kind:"source-symbol",ref:"src/agent/tools/skill-executor.ts (execute: depth >= maxDepth branch)",detail:"returns buildSkillMaxDepthRefusal(depth, maxDepth)"}]}}var ma="tool-failure-density",er="flaky_tool",Vc="refusal_only_tool",Yc="tool-failure-flaky-tool",APe="tool-failure-refusal-only-tool";async function CPe(){let e=f6(),t=qc(),n=[_e({name:"in-default-enabled-set",description:`${ma} runs in a default scan`,pass:e.includes(ma),expected:`defaultEnabledDetectorNames() includes "${ma}"`,actual:`[${e.join(", ")}]`}),_e({name:"not-opt-in",description:`${ma} is not in the disabled-by-default set`,pass:!t.includes(ma),expected:`disabledByDefaultDetectorNames() excludes "${ma}"`,actual:`[${t.join(", ")}]`})],r=[{kind:"config-value",ref:"DETECTOR_REGISTRY['tool-failure-density'].enabledByDefault",detail:String(e.includes(ma))}];return{checks:n,evidence:r}}function vt(e,t,n){let r={phase:"completed",toolUseId:`tu-${e}`,name:t,resultBytes:128,isError:n.isError,truncated:!1,durationMs:10};return n.circuitBreaker===!0&&(r.circuitBreaker=!0),n.failureClass!==void 0&&(r.failureClass=n.failureClass),JSON.stringify({ts:"2026-06-20T10:00:00.000Z",seq:e,kind:"tool_call",payload:r})}function pI(e,t){let n=`state/witness/${e}/trace.jsonl`;return Kc({sessionId:e,tracePath:n,relativeTracePath:n,content:t.join(`
2080
+ Re-run with --force to add another, --no-write to preview, or inspect with 'afk improve proposals show ${l[0]}'.`),process.exit(1)}}let o=n.id??B5(t),i=F5(r,{proposalId:o});if(n.write===!1){n.json?console.log(JSON.stringify(i,null,2)):(console.log("(preview \u2014 not persisted; remove --no-write to save)"),console.log(""),console.log(uv(i)));return}let s=N5(i);if(n.json){console.log(JSON.stringify({...i,_paths:s},null,2));return}console.log(`Wrote proposal: ${s.proposalId}`),console.log(` json: ${s.jsonPath}`),console.log(` md: ${s.markdownPath}`),console.log(` risk: ${i.riskLevel} \xB7 root cause: ${i.rootCauseClass} \xB7 approval required: ${i.scopeFreeze.requiresExplicitApproval?"yes":"no"}`)}catch(r){J(r)}})}function W5(e){let t=e.command("proposals").description("Inspect improvement proposals on disk");t.command("list").description("List all proposals, newest first").option("--card <slug>","Filter by card slug").option("--risk <level>","Filter by risk: low | medium | high").option("--json","Emit JSON instead of a table",!1).action(n=>{try{let r=dI();if(n.card&&(r=r.filter(s=>s.cardSlug===n.card)),n.risk&&(r=r.filter(s=>s.riskLevel===n.risk)),n.json){console.log(JSON.stringify(r,null,2));return}if(r.length===0){console.log("No proposals found.");return}let o="PROPOSAL ID | CARD | RISK | STATUS | CREATED",i="-".repeat(o.length);console.log(o),console.log(i);for(let s of r)console.log([s.proposalId.padEnd(64).slice(0,64),s.cardSlug.padEnd(44).slice(0,44),s.riskLevel.padEnd(6),s.status.padEnd(9),s.createdAt].join(" | "))}catch(r){J(r)}}),t.command("show <id>").description("Print a proposal by id").option("--json","Emit raw JSON instead of rendered markdown",!1).action((n,r)=>{try{let o=ym(n);if(o||(console.error(`Proposal not found: ${n}`),process.exit(1)),r.json){console.log(JSON.stringify(o,null,2));return}console.log(uv(o))}catch(o){J(o)}})}import{createHash as K5}from"crypto";import{existsSync as kPe,readFileSync as TPe}from"fs";var Mn=class extends Error{code;constructor(t,n){super(t),this.name="EvalGenError",this.code=n}};function G5(e,t){if(!kPe(e))throw new Mn(`replay-fixture: source trace not found: ${e}`,"source-not-found");let n=t.startLine??1;if(n!==1)throw new Mn(`replay-fixture: only startLine=1 (prefix slice) is supported in Sprint 3 (got ${n})`,"unsupported-window");let r=TPe(e);if(r.length===0)throw new Mn(`replay-fixture: source trace is empty: ${e}`,"source-empty");let o=EPe(r),i=o.length,s=-1;for(let d=0;d<o.length;d++){let p=o[d];if(p.contentEnd===p.start)continue;let f=r.subarray(p.start,p.contentEnd).toString("utf8"),g;try{g=JSON.parse(f)}catch{continue}if(g!==null&&typeof g=="object"&&"seq"in g&&typeof g.seq=="number"&&g.seq===t.endSeq){s=d+1;break}}if(s===-1)throw new Mn(`replay-fixture: seq ${t.endSeq} not found in ${e} (scanned ${i} lines)`,"seq-not-found");let l=o[s-1].byteEnd,c=Buffer.from(r.subarray(0,l)),u=K5("sha256").update(c).digest("hex");return{bytes:c,startLine:1,endLine:s,sliceLineCount:s,sliceSha256:u,sourceLineCount:i}}function dv(e){return K5("sha256").update(e).digest("hex")}function EPe(e){let t=[],n=0;for(let r=0;r<e.length;r++)e[r]===10&&(t.push({start:n,contentEnd:r,byteEnd:r+1}),n=r+1);return n<e.length&&t.push({start:n,contentEnd:e.length,byteEnd:e.length}),t}import{randomBytes as WPe}from"crypto";import{existsSync as yv,mkdirSync as n3,readFileSync as r3,readdirSync as KPe,renameSync as GPe,writeFileSync as o3}from"fs";import{join as i3,relative as qPe}from"path";G();zr();ja();_d();Ky();var q5=400;function cn(e){let n=(typeof e=="string"?e:String(e)).replace(/\s+/g," ").trim();return n.length>q5?n.slice(0,q5-1)+"\u2026":n}function _e(e){return{name:e.name,description:e.description,status:e.status??(e.pass?"pass":"fail"),expected:cn(e.expected),actual:cn(e.actual)}}var bm="eval_run_probe_tool";async function RPe(){let e=Ua,t=0,n=async()=>(t+=1,{content:"probe-ok"}),r=new Ft({handlers:new Map([[bm,n]]),schemas:[],hookRegistry:void 0,permissions:{allowedTools:[bm]}}),o=new AbortController().signal,i=h=>({id:"eval-run-probe",name:bm,input:h,signal:o}),s={probe:"byte-identical-input"},a=[];for(let h=0;h<e-1;h++)a.push(await r.execute(i(s)));let l=t,c=await r.execute(i(s)),u=t,d=await r.execute(i({probe:"a-different-input"})),p=a.every(h=>h.isError!==!0&&h.circuitBreaker!==!0),f=[_e({name:"executes-below-threshold",description:`First ${e-1} byte-identical calls execute without tripping`,pass:p&&l===e-1,expected:`${e-1} clean executions; handler runs ${e-1}\xD7`,actual:`${a.filter(h=>h.isError!==!0).length} clean; handler ran ${l}\xD7`}),_e({name:"trips-at-threshold",description:`Call #${e} is short-circuited with isError + circuitBreaker, handler skipped`,pass:c.isError===!0&&c.circuitBreaker===!0&&u===l,expected:"isError=true, circuitBreaker=true, handler not re-run",actual:`isError=${c.isError??!1}, circuitBreaker=${c.circuitBreaker??!1}, handler ran ${u}\xD7`}),_e({name:"breaker-message-is-actionable",description:"The synthetic block names the looping tool and reads as a stop nudge",pass:/circuit breaker/i.test(c.content)&&c.content.includes(bm),expected:`mentions "circuit breaker" and the tool name "${bm}"`,actual:c.content}),_e({name:"resets-on-different-input",description:"A different-input call after a trip resets the consecutive counter and executes",pass:d.isError!==!0&&d.circuitBreaker!==!0&&t===u+1,expected:"executes (no breaker), handler runs once more",actual:`isError=${d.isError??!1}, circuitBreaker=${d.circuitBreaker??!1}, handler ran ${t}\xD7`})],g=[{kind:"config-value",ref:"src/agent/tools/dispatcher.ts#REPEAT_CIRCUIT_BREAKER_THRESHOLD",detail:String(e)},{kind:"observed-behavior",ref:"SessionToolDispatcher.execute",detail:`handler ran ${u}\xD7 across ${e} byte-identical calls; call #${e} short-circuited (circuitBreaker=${c.circuitBreaker??!1})`}];return{checks:f,evidence:g}}async function xPe(){let n=Bh(3,3);return{checks:[_e({name:"refusal-states-depth",description:"Refusal reports the depth that was hit and the max",pass:n.includes("nesting depth 3 (max 3)"),expected:'mentions "nesting depth 3 (max 3)"',actual:n}),_e({name:"recovery-hint-present",description:"Refusal carries the recovery hint clause",pass:n.includes(Vo),expected:"contains SKILL_MAX_DEPTH_RECOVERY_HINT",actual:n}),_e({name:"hint-directs-inline-work",description:"Hint tells the model to work inline instead of delegating further",pass:/perform the work inline/i.test(Vo)&&/skill\/agent\/compose/i.test(Vo),expected:'hint mentions "perform the work inline" and "skill/agent/compose"',actual:Vo})],evidence:[{kind:"source-symbol",ref:"src/agent/tools/skill-depth-message.ts#buildSkillMaxDepthRefusal",detail:n},{kind:"source-symbol",ref:"src/agent/tools/skill-executor.ts (execute: depth >= maxDepth branch)",detail:"returns buildSkillMaxDepthRefusal(depth, maxDepth)"}]}}var ma="tool-failure-density",er="flaky_tool",Vc="refusal_only_tool",Yc="tool-failure-flaky-tool",APe="tool-failure-refusal-only-tool";async function CPe(){let e=f5(),t=qc(),n=[_e({name:"in-default-enabled-set",description:`${ma} runs in a default scan`,pass:e.includes(ma),expected:`defaultEnabledDetectorNames() includes "${ma}"`,actual:`[${e.join(", ")}]`}),_e({name:"not-opt-in",description:`${ma} is not in the disabled-by-default set`,pass:!t.includes(ma),expected:`disabledByDefaultDetectorNames() excludes "${ma}"`,actual:`[${t.join(", ")}]`})],r=[{kind:"config-value",ref:"DETECTOR_REGISTRY['tool-failure-density'].enabledByDefault",detail:String(e.includes(ma))}];return{checks:n,evidence:r}}function vt(e,t,n){let r={phase:"completed",toolUseId:`tu-${e}`,name:t,resultBytes:128,isError:n.isError,truncated:!1,durationMs:10};return n.circuitBreaker===!0&&(r.circuitBreaker=!0),n.failureClass!==void 0&&(r.failureClass=n.failureClass),JSON.stringify({ts:"2026-06-20T10:00:00.000Z",seq:e,kind:"tool_call",payload:r})}function pI(e,t){let n=`state/witness/${e}/trace.jsonl`;return Kc({sessionId:e,tracePath:n,relativeTracePath:n,content:t.join(`
2081
2081
  `)+`
2082
- `,sessionMtimeMs:0})}function _Pe(){let e=pI("tfd-sess-a",[vt(0,er,{isError:!1}),vt(1,er,{isError:!0,failureClass:"timeout"}),vt(2,er,{isError:!0}),vt(3,er,{isError:!0,failureClass:"policy-refusal"}),vt(4,er,{isError:!0,circuitBreaker:!0})]),t=pI("tfd-sess-b",[vt(0,er,{isError:!0}),vt(1,er,{isError:!1}),vt(2,er,{isError:!0,failureClass:"permission-denied"}),vt(3,er,{isError:!0,failureClass:"abort"}),vt(4,er,{isError:!0,failureClass:"hook-block"}),vt(5,er,{isError:!0,failureClass:"elicitation-declined"})]),n=pI("tfd-sess-c",[vt(0,Vc,{isError:!1}),vt(1,Vc,{isError:!0,failureClass:"policy-refusal"}),vt(2,Vc,{isError:!0,failureClass:"policy-refusal"}),vt(3,Vc,{isError:!0,failureClass:"permission-denied"}),vt(4,Vc,{isError:!0,failureClass:"hook-block"}),vt(5,Vc,{isError:!0,failureClass:"abort"})]);return[e,t,n]}function pv(e,t){let n=e[t];return typeof n=="number"?n:void 0}function mI(e){let t={};if(e===null||typeof e!="object")return t;for(let[n,r]of Object.entries(e))typeof r=="number"&&(t[n]=r);return t}function z6(e,t){let n=mI(e),r=Object.keys(n),o=Object.keys(t);if(r.length!==o.length)return!1;for(let i of o)if(n[i]!==t[i])return!1;return!0}function IPe(e){return Array.isArray(e)?e.filter(t=>typeof t=="number"):[]}function PPe(e){return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}function MPe(){let e=_Pe(),t=Gc(e,{}),n=t.find(E=>E.slug===Yc),r=t.find(E=>E.slug===APe),o=n?.detail??{},i=pv(o,"failureCount"),s=pv(o,"totalCalls"),a=pv(o,"failureRate"),l=pv(o,"affectedSessionCount"),c=mI(o.failureClassBreakdown),u=mI(o.excludedByClass),d=PPe(o.sessionIds).slice().sort(),p=IPe(o.seqs),f=Gc(e,{minFailures:4}),g=Gc(e,{minFailureRate:.7}),h=!f.some(E=>E.slug===Yc),y=!g.some(E=>E.slug===Yc),b={"policy-refusal":1,"permission-denied":1,abort:1,"hook-block":1,"elicitation-declined":1},w={timeout:1,unclassified:2},k=[_e({name:"classification-fires-on-dual-threshold",description:"A tool clearing BOTH the failure-count and failure-rate floors yields exactly one card at the recorded magnitude",pass:t.length===1&&n!==void 0&&i===3&&s===5&&a===.6,expected:`1 card '${Yc}' with failureCount=3, totalCalls=5, failureRate=0.6`,actual:n===void 0?`no '${Yc}' card; ${t.length} card(s): [${t.map(E=>E.slug).join(", ")}]`:`${t.length} card(s); failureCount=${i}, totalCalls=${s}, failureRate=${a}`}),_e({name:"classification-excludes-system-said-no-classes",description:"policy-refusal / permission-denied / hook-block / abort / elicitation-declined are excluded from BOTH numerator and denominator and never manufacture a card alone",pass:z6(u,b)&&i===3&&s===5&&r===void 0,expected:"excludedByClass={policy-refusal:1,permission-denied:1,abort:1,hook-block:1,elicitation-declined:1}; counts not inflated; refusal-only tool yields NO card",actual:`excludedByClass=${JSON.stringify(u)}; failureCount=${i}, totalCalls=${s}; refusal_only_tool card ${r===void 0?"absent":"PRESENT"}`}),_e({name:"classification-excludes-circuit-breaker",description:"A circuitBreaker-synthesised completion is skipped before classification \u2014 it inflates neither totalCalls nor the unclassified count, and never lands in excludedByClass",pass:s===5&&c.unclassified===2&&u.circuitBreaker===void 0,expected:"totalCalls=5 (breaker not counted); unclassified=2 (breaker not folded in); no circuitBreaker key in excludedByClass",actual:`totalCalls=${s}; unclassified=${c.unclassified??0}; excludedByClass keys=[${Object.keys(u).join(", ")}]`}),_e({name:"classification-counts-timeout-and-unclassified",description:"timeout and unclassified (no failureClass) failures DO count toward the failure stats",pass:z6(c,w),expected:"failureClassBreakdown={timeout:1,unclassified:2}",actual:`failureClassBreakdown=${JSON.stringify(c)}`}),_e({name:"classification-respects-thresholds",description:"The card drops out when EITHER the count floor or the rate floor is raised above the recorded magnitude (dual AND threshold)",pass:h&&y,expected:"minFailures=4 \u2192 no card (count gate); minFailureRate=0.7 \u2192 no card (rate gate)",actual:`count gate ${h?"held":"LEAKED"}; rate gate ${y?"held":"LEAKED"}`}),_e({name:"classification-reports-affected-sessions-and-seqs",description:"The card reports the distinct affected sessions and per-failure seqs in deterministic order",pass:l===2&&JSON.stringify(d)===JSON.stringify(["tfd-sess-a","tfd-sess-b"])&&JSON.stringify(p)===JSON.stringify([1,2,0]),expected:"affectedSessionCount=2; sessionIds=[tfd-sess-a,tfd-sess-b]; seqs=[1,2,0]",actual:`affectedSessionCount=${l}; sessionIds=[${d.join(",")}]; seqs=[${p.join(",")}]`})],S=[{kind:"source-symbol",ref:"src/improve/scan/detectors/tool-failure-density.ts#detectToolFailureDensity",detail:n===void 0?`synthetic corpus \u2192 ${t.length} card(s); '${Yc}' absent`:`synthetic corpus \u2192 flaky_tool ${i}/${s} (rate ${a}); breakdown ${JSON.stringify(c)}`},{kind:"observed-behavior",ref:"detectToolFailureDensity (EXCLUDED_FAILURE_CLASSES + circuitBreaker exclusion)",detail:`excludedByClass=${JSON.stringify(u)}; refusal_only_tool card ${r===void 0?"absent":"PRESENT"}`}];return{checks:k,evidence:S}}async function OPe(){let e=await CPe(),t=MPe();return{checks:[...e.checks,...t.checks],evidence:[...e.evidence,...t.evidence]}}async function $Pe(){let e=Rs("abort"),t=Rs("model_end_turn"),n=[_e({name:"abort-closure-has-guidance",description:"An abort closure maps to a non-empty recovery hint",pass:typeof e=="string"&&e.trim().length>0,expected:"non-empty guidance string for reason=abort",actual:e===null?"null (no guidance)":cn(e)}),_e({name:"guidance-names-a-recovery-action",description:"The abort hint names a concrete next action (resume / re-run)",pass:e!==null&&/\b(resume|re-run|rerun|retry)\b/i.test(e),expected:"hint mentions resume / re-run",actual:e===null?"null":cn(e)}),_e({name:"guidance-is-the-canonical-constant",description:"The wired hint is the exported CLOSURE_ABORT_RECOVERY_HINT (no drift)",pass:e===Lx,expected:'buildClosureGuidance("abort") === CLOSURE_ABORT_RECOVERY_HINT',actual:e===null?"null":cn(e)}),_e({name:"benign-closure-has-no-guidance",description:"A clean model_end_turn close carries no false-positive guidance",pass:t===null,expected:"null for reason=model_end_turn",actual:t===null?"null":cn(t)})],r=[{kind:"source-symbol",ref:"src/agent/session/closure-guidance.ts#buildClosureGuidance",detail:e===null?"null":cn(e)},{kind:"source-symbol",ref:"src/agent/session/agent-session.ts (emitClosure: attaches guidance to closure event)",detail:"buildClosureGuidance(reason) \u2192 closure payload .guidance"}];return{checks:n,evidence:r}}var fI=Object.freeze([{id:"repeat-loop-circuit-breaker",patternId:"repeated-tool-use",title:"Repeat-loop circuit breaker trips at the consecutive-identical threshold",run:RPe},{id:"skill-max-depth-recovery-hint",patternId:"subagent-block",title:"Skill max-depth refusal carries an actionable recovery hint",run:xPe},{id:"tool-failure-density-enabled",patternId:"tool-failure-density",title:"tool-failure-density detector is enabled by default and classifies a known failure mix correctly",run:OPe},{id:"closure-abort-recovery-hint",patternId:"closure-anomaly",title:"Anomalous abort closure carries an actionable recovery hint",run:$Pe}]);function mv(e){return fI.find(t=>t.patternId===e)}function J6(){return fI.map(e=>e.patternId)}function V6(){return fI.map(e=>e.id)}ja();Ky();var gv="replay:",Y6=`${gv}fixture-reproduces-pattern`,e3=`${gv}guardrail-neutralizes-recorded-loop`,X6=`${gv}fixture-reproduces-closure-anomaly`,t3=`${gv}guardrail-guides-recorded-closure`,Q6="The committed fixture still reproduces the recorded repeated-tool-use loop when re-scanned by the detector",DPe=Object.freeze({replay:"byte-identical-input"}),FPe=async(e,t)=>{let n=async()=>({content:"replay-probe-ok"}),r=new Ft({handlers:new Map([[e,n]]),schemas:[],hookRegistry:void 0,permissions:{allowedTools:[e]}}),o=new AbortController().signal,i=null,s=0;for(let a=1;a<=t;a++){let l={id:`replay-${a}`,name:e,input:DPe,signal:o},c=await r.execute(l);if(s=a,c.circuitBreaker===!0){i=a;break}}return{trippedAtCall:i,callsDriven:s}};function fv(e){let t=e.detail.runLength;return typeof t=="number"?t:0}async function LPe(e,t,n){let r=[],o=[],i=t.toString("utf8"),s=Kc({sessionId:e.replay.sourceSessionId,tracePath:e.replay.sourceTracePath,relativeTracePath:e.replay.sourceTracePath,content:i,sessionMtimeMs:0}),a=nv([s],{minRepeats:vo}),l=e.provenance.fingerprintAtGeneration,c=l?a.find(w=>w.detail.fingerprint===l):void 0,u=[...a].sort((w,k)=>fv(k)-fv(w))[0],d=c??u;if(d===void 0)return r.push(_e({name:Y6,description:Q6,pass:!1,status:"skipped",expected:l?`detector finds a run with fingerprint ${l.slice(0,12)}\u2026`:"detector finds \u22651 repeated-tool-use run in the fixture",actual:`detector found ${a.length} run(s); none matched \u2014 replay skipped (eval-case may be stale or misgenerated)`})),o.push({kind:"fixture",ref:e.replay.fixturePath,detail:"fixture did not reproduce the repeated-tool-use pattern; replay skipped (no loop to re-drive)"}),{checks:r,evidence:o};r.push(_e({name:Y6,description:Q6,pass:!0,expected:l?`detector finds a run with fingerprint ${l.slice(0,12)}\u2026`:"detector finds \u22651 repeated-tool-use run in the fixture",actual:`found '${String(d.detail.toolName)}' \xD7${fv(d)}`}));let p=String(d.detail.toolName),f=fv(d),g=n.driveLoop??FPe,h=Math.min(f,Ua),y=await g(p,h),b=y.trippedAtCall!==null&&y.trippedAtCall<=f;return r.push(_e({name:e3,description:"Re-driving the recorded loop through the live guardrail trips the circuit breaker at or before the recorded length",pass:b,expected:`circuit breaker trips at call \u2264 ${f} (recorded run length)`,actual:y.trippedAtCall===null?`no trip within ${y.callsDriven} call(s) \u2014 recorded loop of ${f} would still complete`:`tripped at call ${y.trippedAtCall}`})),o.push({kind:"observed-behavior",ref:"SessionToolDispatcher.execute (repeat-loop circuit breaker)",detail:`'${p}' recorded \xD7${f}; live breaker ${y.trippedAtCall===null?"did NOT trip":`tripped at call ${y.trippedAtCall}`} (threshold ${Ua})`},{kind:"fixture",ref:e.replay.fixturePath,detail:`replayed recorded loop on '${p}' (run length ${f})`}),{checks:r,evidence:o}}function NPe(e){let t=e.detail.closureReason;return typeof t=="string"?t:null}function BPe(e){let t=e.detail.seqs;return Array.isArray(t)?t.filter(n=>typeof n=="number"):[]}var Z6="The committed fixture still reproduces the recorded anomalous closure when re-scanned by the detector";async function UPe(e,t,n){let r=[],o=[],i=t.toString("utf8"),s=Kc({sessionId:e.replay.sourceSessionId,tracePath:e.replay.sourceTracePath,relativeTracePath:e.replay.sourceTracePath,content:i,sessionMtimeMs:0}),a=rv([s],{minOccurrences:1}),l=Math.max(...e.replay.evidenceEventIndices),u=a.find(h=>BPe(h).includes(l))??a[0];if(u===void 0)return r.push(_e({name:X6,description:Z6,pass:!1,status:"skipped",expected:"detector finds \u22651 anomalous closure in the fixture",actual:`detector found ${a.length} closure-anomaly finding(s); none matched \u2014 replay skipped (eval-case may be stale or misgenerated)`})),o.push({kind:"fixture",ref:e.replay.fixturePath,detail:"fixture did not reproduce an anomalous closure; replay skipped (no closure to re-drive)"}),{checks:r,evidence:o};let d=NPe(u)??"";r.push(_e({name:X6,description:Z6,pass:!0,expected:"detector finds \u22651 anomalous closure in the fixture",actual:`found closure.reason='${d}' (seq ${l})`}));let f=(n.buildGuidance??Rs)(d),g=f!==null&&f.trim().length>0;return r.push(_e({name:t3,description:"Re-driving the recorded closure reason through the live guardrail yields actionable recovery guidance",pass:g,expected:`buildClosureGuidance('${d}') returns a non-empty recovery hint`,actual:g?cn(f):`no guidance for reason '${d}' \u2014 the recorded closure anomaly would still surface with no recovery path`})),o.push({kind:"observed-behavior",ref:"buildClosureGuidance (closure-anomaly recovery hint)",detail:`closure.reason='${d}'; live guardrail ${g?"returned a recovery hint":"returned no guidance"}`},{kind:"fixture",ref:e.replay.fixturePath,detail:`replayed recorded closure reason '${d}'`}),{checks:r,evidence:o}}var jPe=Object.freeze([{patternId:"repeated-tool-use",run:LPe},{patternId:"closure-anomaly",run:UPe}]),HPe=[e3,t3];function gI(e){return HPe.includes(e)}function hv(e){return jPe.find(t=>t.patternId===e)}function hI(e){return hv(e)?"`afk improve eval-run` re-drives this recorded failure and tests neutralisation.":mv(e)?"`afk improve eval-run` runs a narrower guardrail-presence contract; it does not prove this recorded failure is fixed.":"`afk improve eval-run` reports `unsupported` (exit 3); this assertion is not enforced."}function s3(e,t={}){let n=(t.now??(()=>new Date))(),r=zPe(n),o=t.randomSuffix!==void 0?t.randomSuffix():WPe(3).toString("hex");if(!/^[0-9a-f]{6}$/.test(o))throw new Error(`generateEvalCaseId: randomSuffix must be 6 lowercase hex chars (got '${o}')`);return`${e}-eval-${r}-${o}`}function zPe(e){let t=e.getUTCFullYear(),n=String(e.getUTCMonth()+1).padStart(2,"0"),r=String(e.getUTCDate()).padStart(2,"0");return`${t}${n}${r}`}function a3(e,t){if(t.evidenceRowIndex<0||t.evidenceRowIndex>=e.evidence.length)throw new Mn(`buildEvalCase: evidence row ${t.evidenceRowIndex} out of range (card has ${e.evidence.length} row(s))`,"evidence-row-out-of-range");let n=e.evidence[t.evidenceRowIndex];if(n.eventIndices.length===0)throw new Mn(`buildEvalCase: evidence row ${t.evidenceRowIndex} has no eventIndices`,"seq-not-found");let r=Math.max(...n.eventIndices),i=(t.resolveTraceAbsPath??JPe)(n.tracePath),s=G6(i,{endSeq:r}),a=(t.now??(()=>new Date))().toISOString(),l=sI(t.evalCaseId),c=qPe(ve(),l),u=typeof e.detail.detector=="string"?e.detail.detector:e.pattern,d=typeof e.detail.fingerprint=="string"?e.detail.fingerprint:null,p=t.proposalId??null,f={schemaVersion:1,evalCaseId:t.evalCaseId,cardSlug:e.slug,proposalId:p,title:VPe(e,r),createdAt:a,kind:"replay",replay:{sourceSessionId:n.sessionId,sourceTracePath:n.tracePath,fixturePath:c,evidenceRowIndex:t.evidenceRowIndex,evidenceEventIndices:[...n.eventIndices],sliceLineRange:{startLine:s.startLine,endLine:s.endLine},sliceLineCount:s.sliceLineCount,sliceSha256:s.sliceSha256},assertion:{kind:"pattern-absent",patternId:e.pattern,detectorVersion:u,rationale:YPe({patternId:e.pattern,detectorVersion:u,endSeq:r,sliceLineCount:s.sliceLineCount,sessionId:n.sessionId})},provenance:{detectorAtGeneration:u,fingerprintAtGeneration:d,cardOccurrenceCountAtGeneration:e.occurrenceCount,cardLastSeenAtGeneration:e.lastSeen,generatedBy:"replay-fixture"},status:"draft",notes:[]};return lv.parse(f),{evalCase:f,sliceBytes:s.bytes}}function JPe(e){return i3(ve(),e)}function VPe(e,t){let n="Replay [pattern-absent]: ",r=` (through seq ${t})`,o=200-n.length-r.length,i=e.title.length>o?e.title.slice(0,o-1)+"\u2026":e.title;return`${n}${i}${r}`.slice(0,200)}function YPe(e){let t=e.sessionId.slice(0,8),n=hI(e.patternId);return`After the proposed fix lands, replaying the prefix [seq 0..${e.endSeq}] (${e.sliceLineCount} lines, session ${t}\u2026) through ${e.detectorVersion} must produce zero findings for '${e.patternId}' with the fingerprint at generation time. `+n}function l3(e,t){let n=lv.parse(e),r=Ii();yv(r)||n3(r,{recursive:!0});let o=iI(n.evalCaseId),i=sI(n.evalCaseId),s=o6(n.evalCaseId);QPe(i,t);let a=dv(r3(i));if(a!==n.replay.sliceSha256)throw new Mn(`writeEvalCase: fixture sha256 mismatch after write (expected ${n.replay.sliceSha256}, got ${a}, path ${i})`,"fixture-mismatch");return Ze(o,JSON.stringify(n,null,2),438),Ze(s,bv(n),438),XPe({timestamp:new Date().toISOString(),event:"created",evalCaseId:n.evalCaseId,cardSlug:n.cardSlug,proposalId:n.proposalId,kind:n.kind}),{evalCaseId:n.evalCaseId,jsonPath:o,fixturePath:i,markdownPath:s}}function bv(e){let t=[];if(t.push(`# ${e.evalCaseId} \u2014 \`${e.kind}\` \u2014 \`${e.status}\``),t.push(""),t.push(e.title),t.push(""),t.push(`**Card:** \`${e.cardSlug}\` \xB7 **Proposal:** ${e.proposalId?`\`${e.proposalId}\``:"_(none)_"} \xB7 **Created:** ${e.createdAt}`),t.push(""),t.push("> **How to run this.** This file is a CONTRACT; the fixture"),t.push("> beside it is the executable input. Run it with"),t.push("> `afk improve eval-run "+e.evalCaseId+"`."),t.push("> "+hI(e.assertion.patternId)),t.push(""),t.push("## Replay fixture"),t.push(""),t.push(`- **Source session:** \`${e.replay.sourceSessionId}\``),t.push(`- **Source trace:** \`${e.replay.sourceTracePath}\``),t.push(`- **Fixture:** \`${e.replay.fixturePath}\``),t.push(`- **Evidence row:** index ${e.replay.evidenceRowIndex} (seqs ${e.replay.evidenceEventIndices.join(", ")})`),t.push(`- **Slice:** lines ${e.replay.sliceLineRange.startLine}\u2013${e.replay.sliceLineRange.endLine} (${e.replay.sliceLineCount} lines)`),t.push(`- **SHA-256:** \`${e.replay.sliceSha256}\``),t.push(""),t.push("## Assertion"),t.push(""),t.push(`- **Kind:** \`${e.assertion.kind}\``),t.push(`- **Pattern:** \`${e.assertion.patternId}\``),t.push(`- **Detector:** \`${e.assertion.detectorVersion}\``),t.push(""),t.push(e.assertion.rationale),t.push(""),t.push("## Provenance"),t.push(""),t.push(`- **Detector at generation:** \`${e.provenance.detectorAtGeneration}\``),t.push(`- **Fingerprint at generation:** ${e.provenance.fingerprintAtGeneration?`\`${e.provenance.fingerprintAtGeneration}\``:"_(none \u2014 detector has no fingerprint)_"}`),t.push(`- **Card occurrence count at generation:** ${e.provenance.cardOccurrenceCountAtGeneration}`),t.push(`- **Card lastSeen at generation:** ${e.provenance.cardLastSeenAtGeneration}`),t.push(`- **Generated by:** \`${e.provenance.generatedBy}\``),t.push(""),t.push("## Triage notes"),t.push(""),e.notes.length===0)t.push("_(none)_");else for(let n of e.notes)t.push(`- _${n.at}_ \u2014 ${n.text}`);return t.push(""),t.join(`
2083
- `)}function yI(){let e=Ii();if(!yv(e))return[];let t=[];for(let n of KPe(e)){if(!n.endsWith(".json")||n.startsWith(".")||n.endsWith(".fixture.jsonl"))continue;let r=c3(i3(e,n));r&&t.push({evalCaseId:r.evalCaseId,cardSlug:r.cardSlug,proposalId:r.proposalId,title:r.title,kind:r.kind,status:r.status,patternId:r.assertion.patternId,createdAt:r.createdAt,sliceSha256:r.replay.sliceSha256})}return t.sort((n,r)=>n.createdAt!==r.createdAt?n.createdAt<r.createdAt?1:-1:n.evalCaseId<r.evalCaseId?-1:1),t}function wm(e){return c3(iI(e))}function wv(e){return yI().filter(t=>t.cardSlug===e).map(t=>wm(t.evalCaseId)).filter(t=>t!==void 0)}function c3(e){if(yv(e))try{let t=r3(e,"utf-8"),n=JSON.parse(t),r=lv.safeParse(n);return r.success?r.data:void 0}catch{return}}function XPe(e){let t=b6.parse(e),n=r6(),r=Ii();yv(r)||n3(r,{recursive:!0});try{o3(n,JSON.stringify(t)+`
2082
+ `,sessionMtimeMs:0})}function _Pe(){let e=pI("tfd-sess-a",[vt(0,er,{isError:!1}),vt(1,er,{isError:!0,failureClass:"timeout"}),vt(2,er,{isError:!0}),vt(3,er,{isError:!0,failureClass:"policy-refusal"}),vt(4,er,{isError:!0,circuitBreaker:!0})]),t=pI("tfd-sess-b",[vt(0,er,{isError:!0}),vt(1,er,{isError:!1}),vt(2,er,{isError:!0,failureClass:"permission-denied"}),vt(3,er,{isError:!0,failureClass:"abort"}),vt(4,er,{isError:!0,failureClass:"hook-block"}),vt(5,er,{isError:!0,failureClass:"elicitation-declined"})]),n=pI("tfd-sess-c",[vt(0,Vc,{isError:!1}),vt(1,Vc,{isError:!0,failureClass:"policy-refusal"}),vt(2,Vc,{isError:!0,failureClass:"policy-refusal"}),vt(3,Vc,{isError:!0,failureClass:"permission-denied"}),vt(4,Vc,{isError:!0,failureClass:"hook-block"}),vt(5,Vc,{isError:!0,failureClass:"abort"})]);return[e,t,n]}function pv(e,t){let n=e[t];return typeof n=="number"?n:void 0}function mI(e){let t={};if(e===null||typeof e!="object")return t;for(let[n,r]of Object.entries(e))typeof r=="number"&&(t[n]=r);return t}function z5(e,t){let n=mI(e),r=Object.keys(n),o=Object.keys(t);if(r.length!==o.length)return!1;for(let i of o)if(n[i]!==t[i])return!1;return!0}function IPe(e){return Array.isArray(e)?e.filter(t=>typeof t=="number"):[]}function PPe(e){return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}function MPe(){let e=_Pe(),t=Gc(e,{}),n=t.find(E=>E.slug===Yc),r=t.find(E=>E.slug===APe),o=n?.detail??{},i=pv(o,"failureCount"),s=pv(o,"totalCalls"),a=pv(o,"failureRate"),l=pv(o,"affectedSessionCount"),c=mI(o.failureClassBreakdown),u=mI(o.excludedByClass),d=PPe(o.sessionIds).slice().sort(),p=IPe(o.seqs),f=Gc(e,{minFailures:4}),g=Gc(e,{minFailureRate:.7}),h=!f.some(E=>E.slug===Yc),y=!g.some(E=>E.slug===Yc),b={"policy-refusal":1,"permission-denied":1,abort:1,"hook-block":1,"elicitation-declined":1},w={timeout:1,unclassified:2},k=[_e({name:"classification-fires-on-dual-threshold",description:"A tool clearing BOTH the failure-count and failure-rate floors yields exactly one card at the recorded magnitude",pass:t.length===1&&n!==void 0&&i===3&&s===5&&a===.6,expected:`1 card '${Yc}' with failureCount=3, totalCalls=5, failureRate=0.6`,actual:n===void 0?`no '${Yc}' card; ${t.length} card(s): [${t.map(E=>E.slug).join(", ")}]`:`${t.length} card(s); failureCount=${i}, totalCalls=${s}, failureRate=${a}`}),_e({name:"classification-excludes-system-said-no-classes",description:"policy-refusal / permission-denied / hook-block / abort / elicitation-declined are excluded from BOTH numerator and denominator and never manufacture a card alone",pass:z5(u,b)&&i===3&&s===5&&r===void 0,expected:"excludedByClass={policy-refusal:1,permission-denied:1,abort:1,hook-block:1,elicitation-declined:1}; counts not inflated; refusal-only tool yields NO card",actual:`excludedByClass=${JSON.stringify(u)}; failureCount=${i}, totalCalls=${s}; refusal_only_tool card ${r===void 0?"absent":"PRESENT"}`}),_e({name:"classification-excludes-circuit-breaker",description:"A circuitBreaker-synthesised completion is skipped before classification \u2014 it inflates neither totalCalls nor the unclassified count, and never lands in excludedByClass",pass:s===5&&c.unclassified===2&&u.circuitBreaker===void 0,expected:"totalCalls=5 (breaker not counted); unclassified=2 (breaker not folded in); no circuitBreaker key in excludedByClass",actual:`totalCalls=${s}; unclassified=${c.unclassified??0}; excludedByClass keys=[${Object.keys(u).join(", ")}]`}),_e({name:"classification-counts-timeout-and-unclassified",description:"timeout and unclassified (no failureClass) failures DO count toward the failure stats",pass:z5(c,w),expected:"failureClassBreakdown={timeout:1,unclassified:2}",actual:`failureClassBreakdown=${JSON.stringify(c)}`}),_e({name:"classification-respects-thresholds",description:"The card drops out when EITHER the count floor or the rate floor is raised above the recorded magnitude (dual AND threshold)",pass:h&&y,expected:"minFailures=4 \u2192 no card (count gate); minFailureRate=0.7 \u2192 no card (rate gate)",actual:`count gate ${h?"held":"LEAKED"}; rate gate ${y?"held":"LEAKED"}`}),_e({name:"classification-reports-affected-sessions-and-seqs",description:"The card reports the distinct affected sessions and per-failure seqs in deterministic order",pass:l===2&&JSON.stringify(d)===JSON.stringify(["tfd-sess-a","tfd-sess-b"])&&JSON.stringify(p)===JSON.stringify([1,2,0]),expected:"affectedSessionCount=2; sessionIds=[tfd-sess-a,tfd-sess-b]; seqs=[1,2,0]",actual:`affectedSessionCount=${l}; sessionIds=[${d.join(",")}]; seqs=[${p.join(",")}]`})],S=[{kind:"source-symbol",ref:"src/improve/scan/detectors/tool-failure-density.ts#detectToolFailureDensity",detail:n===void 0?`synthetic corpus \u2192 ${t.length} card(s); '${Yc}' absent`:`synthetic corpus \u2192 flaky_tool ${i}/${s} (rate ${a}); breakdown ${JSON.stringify(c)}`},{kind:"observed-behavior",ref:"detectToolFailureDensity (EXCLUDED_FAILURE_CLASSES + circuitBreaker exclusion)",detail:`excludedByClass=${JSON.stringify(u)}; refusal_only_tool card ${r===void 0?"absent":"PRESENT"}`}];return{checks:k,evidence:S}}async function OPe(){let e=await CPe(),t=MPe();return{checks:[...e.checks,...t.checks],evidence:[...e.evidence,...t.evidence]}}async function $Pe(){let e=Rs("abort"),t=Rs("model_end_turn"),n=[_e({name:"abort-closure-has-guidance",description:"An abort closure maps to a non-empty recovery hint",pass:typeof e=="string"&&e.trim().length>0,expected:"non-empty guidance string for reason=abort",actual:e===null?"null (no guidance)":cn(e)}),_e({name:"guidance-names-a-recovery-action",description:"The abort hint names a concrete next action (resume / re-run)",pass:e!==null&&/\b(resume|re-run|rerun|retry)\b/i.test(e),expected:"hint mentions resume / re-run",actual:e===null?"null":cn(e)}),_e({name:"guidance-is-the-canonical-constant",description:"The wired hint is the exported CLOSURE_ABORT_RECOVERY_HINT (no drift)",pass:e===Lx,expected:'buildClosureGuidance("abort") === CLOSURE_ABORT_RECOVERY_HINT',actual:e===null?"null":cn(e)}),_e({name:"benign-closure-has-no-guidance",description:"A clean model_end_turn close carries no false-positive guidance",pass:t===null,expected:"null for reason=model_end_turn",actual:t===null?"null":cn(t)})],r=[{kind:"source-symbol",ref:"src/agent/session/closure-guidance.ts#buildClosureGuidance",detail:e===null?"null":cn(e)},{kind:"source-symbol",ref:"src/agent/session/agent-session.ts (emitClosure: attaches guidance to closure event)",detail:"buildClosureGuidance(reason) \u2192 closure payload .guidance"}];return{checks:n,evidence:r}}var fI=Object.freeze([{id:"repeat-loop-circuit-breaker",patternId:"repeated-tool-use",title:"Repeat-loop circuit breaker trips at the consecutive-identical threshold",run:RPe},{id:"skill-max-depth-recovery-hint",patternId:"subagent-block",title:"Skill max-depth refusal carries an actionable recovery hint",run:xPe},{id:"tool-failure-density-enabled",patternId:"tool-failure-density",title:"tool-failure-density detector is enabled by default and classifies a known failure mix correctly",run:OPe},{id:"closure-abort-recovery-hint",patternId:"closure-anomaly",title:"Anomalous abort closure carries an actionable recovery hint",run:$Pe}]);function mv(e){return fI.find(t=>t.patternId===e)}function J5(){return fI.map(e=>e.patternId)}function V5(){return fI.map(e=>e.id)}ja();Ky();var gv="replay:",Y5=`${gv}fixture-reproduces-pattern`,e3=`${gv}guardrail-neutralizes-recorded-loop`,X5=`${gv}fixture-reproduces-closure-anomaly`,t3=`${gv}guardrail-guides-recorded-closure`,Q5="The committed fixture still reproduces the recorded repeated-tool-use loop when re-scanned by the detector",DPe=Object.freeze({replay:"byte-identical-input"}),FPe=async(e,t)=>{let n=async()=>({content:"replay-probe-ok"}),r=new Ft({handlers:new Map([[e,n]]),schemas:[],hookRegistry:void 0,permissions:{allowedTools:[e]}}),o=new AbortController().signal,i=null,s=0;for(let a=1;a<=t;a++){let l={id:`replay-${a}`,name:e,input:DPe,signal:o},c=await r.execute(l);if(s=a,c.circuitBreaker===!0){i=a;break}}return{trippedAtCall:i,callsDriven:s}};function fv(e){let t=e.detail.runLength;return typeof t=="number"?t:0}async function LPe(e,t,n){let r=[],o=[],i=t.toString("utf8"),s=Kc({sessionId:e.replay.sourceSessionId,tracePath:e.replay.sourceTracePath,relativeTracePath:e.replay.sourceTracePath,content:i,sessionMtimeMs:0}),a=nv([s],{minRepeats:vo}),l=e.provenance.fingerprintAtGeneration,c=l?a.find(w=>w.detail.fingerprint===l):void 0,u=[...a].sort((w,k)=>fv(k)-fv(w))[0],d=c??u;if(d===void 0)return r.push(_e({name:Y5,description:Q5,pass:!1,status:"skipped",expected:l?`detector finds a run with fingerprint ${l.slice(0,12)}\u2026`:"detector finds \u22651 repeated-tool-use run in the fixture",actual:`detector found ${a.length} run(s); none matched \u2014 replay skipped (eval-case may be stale or misgenerated)`})),o.push({kind:"fixture",ref:e.replay.fixturePath,detail:"fixture did not reproduce the repeated-tool-use pattern; replay skipped (no loop to re-drive)"}),{checks:r,evidence:o};r.push(_e({name:Y5,description:Q5,pass:!0,expected:l?`detector finds a run with fingerprint ${l.slice(0,12)}\u2026`:"detector finds \u22651 repeated-tool-use run in the fixture",actual:`found '${String(d.detail.toolName)}' \xD7${fv(d)}`}));let p=String(d.detail.toolName),f=fv(d),g=n.driveLoop??FPe,h=Math.min(f,Ua),y=await g(p,h),b=y.trippedAtCall!==null&&y.trippedAtCall<=f;return r.push(_e({name:e3,description:"Re-driving the recorded loop through the live guardrail trips the circuit breaker at or before the recorded length",pass:b,expected:`circuit breaker trips at call \u2264 ${f} (recorded run length)`,actual:y.trippedAtCall===null?`no trip within ${y.callsDriven} call(s) \u2014 recorded loop of ${f} would still complete`:`tripped at call ${y.trippedAtCall}`})),o.push({kind:"observed-behavior",ref:"SessionToolDispatcher.execute (repeat-loop circuit breaker)",detail:`'${p}' recorded \xD7${f}; live breaker ${y.trippedAtCall===null?"did NOT trip":`tripped at call ${y.trippedAtCall}`} (threshold ${Ua})`},{kind:"fixture",ref:e.replay.fixturePath,detail:`replayed recorded loop on '${p}' (run length ${f})`}),{checks:r,evidence:o}}function NPe(e){let t=e.detail.closureReason;return typeof t=="string"?t:null}function BPe(e){let t=e.detail.seqs;return Array.isArray(t)?t.filter(n=>typeof n=="number"):[]}var Z5="The committed fixture still reproduces the recorded anomalous closure when re-scanned by the detector";async function UPe(e,t,n){let r=[],o=[],i=t.toString("utf8"),s=Kc({sessionId:e.replay.sourceSessionId,tracePath:e.replay.sourceTracePath,relativeTracePath:e.replay.sourceTracePath,content:i,sessionMtimeMs:0}),a=rv([s],{minOccurrences:1}),l=Math.max(...e.replay.evidenceEventIndices),u=a.find(h=>BPe(h).includes(l))??a[0];if(u===void 0)return r.push(_e({name:X5,description:Z5,pass:!1,status:"skipped",expected:"detector finds \u22651 anomalous closure in the fixture",actual:`detector found ${a.length} closure-anomaly finding(s); none matched \u2014 replay skipped (eval-case may be stale or misgenerated)`})),o.push({kind:"fixture",ref:e.replay.fixturePath,detail:"fixture did not reproduce an anomalous closure; replay skipped (no closure to re-drive)"}),{checks:r,evidence:o};let d=NPe(u)??"";r.push(_e({name:X5,description:Z5,pass:!0,expected:"detector finds \u22651 anomalous closure in the fixture",actual:`found closure.reason='${d}' (seq ${l})`}));let f=(n.buildGuidance??Rs)(d),g=f!==null&&f.trim().length>0;return r.push(_e({name:t3,description:"Re-driving the recorded closure reason through the live guardrail yields actionable recovery guidance",pass:g,expected:`buildClosureGuidance('${d}') returns a non-empty recovery hint`,actual:g?cn(f):`no guidance for reason '${d}' \u2014 the recorded closure anomaly would still surface with no recovery path`})),o.push({kind:"observed-behavior",ref:"buildClosureGuidance (closure-anomaly recovery hint)",detail:`closure.reason='${d}'; live guardrail ${g?"returned a recovery hint":"returned no guidance"}`},{kind:"fixture",ref:e.replay.fixturePath,detail:`replayed recorded closure reason '${d}'`}),{checks:r,evidence:o}}var jPe=Object.freeze([{patternId:"repeated-tool-use",run:LPe},{patternId:"closure-anomaly",run:UPe}]),HPe=[e3,t3];function gI(e){return HPe.includes(e)}function hv(e){return jPe.find(t=>t.patternId===e)}function hI(e){return hv(e)?"`afk improve eval-run` re-drives this recorded failure and tests neutralisation.":mv(e)?"`afk improve eval-run` runs a narrower guardrail-presence contract; it does not prove this recorded failure is fixed.":"`afk improve eval-run` reports `unsupported` (exit 3); this assertion is not enforced."}function s3(e,t={}){let n=(t.now??(()=>new Date))(),r=zPe(n),o=t.randomSuffix!==void 0?t.randomSuffix():WPe(3).toString("hex");if(!/^[0-9a-f]{6}$/.test(o))throw new Error(`generateEvalCaseId: randomSuffix must be 6 lowercase hex chars (got '${o}')`);return`${e}-eval-${r}-${o}`}function zPe(e){let t=e.getUTCFullYear(),n=String(e.getUTCMonth()+1).padStart(2,"0"),r=String(e.getUTCDate()).padStart(2,"0");return`${t}${n}${r}`}function a3(e,t){if(t.evidenceRowIndex<0||t.evidenceRowIndex>=e.evidence.length)throw new Mn(`buildEvalCase: evidence row ${t.evidenceRowIndex} out of range (card has ${e.evidence.length} row(s))`,"evidence-row-out-of-range");let n=e.evidence[t.evidenceRowIndex];if(n.eventIndices.length===0)throw new Mn(`buildEvalCase: evidence row ${t.evidenceRowIndex} has no eventIndices`,"seq-not-found");let r=Math.max(...n.eventIndices),i=(t.resolveTraceAbsPath??JPe)(n.tracePath),s=G5(i,{endSeq:r}),a=(t.now??(()=>new Date))().toISOString(),l=sI(t.evalCaseId),c=qPe(ve(),l),u=typeof e.detail.detector=="string"?e.detail.detector:e.pattern,d=typeof e.detail.fingerprint=="string"?e.detail.fingerprint:null,p=t.proposalId??null,f={schemaVersion:1,evalCaseId:t.evalCaseId,cardSlug:e.slug,proposalId:p,title:VPe(e,r),createdAt:a,kind:"replay",replay:{sourceSessionId:n.sessionId,sourceTracePath:n.tracePath,fixturePath:c,evidenceRowIndex:t.evidenceRowIndex,evidenceEventIndices:[...n.eventIndices],sliceLineRange:{startLine:s.startLine,endLine:s.endLine},sliceLineCount:s.sliceLineCount,sliceSha256:s.sliceSha256},assertion:{kind:"pattern-absent",patternId:e.pattern,detectorVersion:u,rationale:YPe({patternId:e.pattern,detectorVersion:u,endSeq:r,sliceLineCount:s.sliceLineCount,sessionId:n.sessionId})},provenance:{detectorAtGeneration:u,fingerprintAtGeneration:d,cardOccurrenceCountAtGeneration:e.occurrenceCount,cardLastSeenAtGeneration:e.lastSeen,generatedBy:"replay-fixture"},status:"draft",notes:[]};return lv.parse(f),{evalCase:f,sliceBytes:s.bytes}}function JPe(e){return i3(ve(),e)}function VPe(e,t){let n="Replay [pattern-absent]: ",r=` (through seq ${t})`,o=200-n.length-r.length,i=e.title.length>o?e.title.slice(0,o-1)+"\u2026":e.title;return`${n}${i}${r}`.slice(0,200)}function YPe(e){let t=e.sessionId.slice(0,8),n=hI(e.patternId);return`After the proposed fix lands, replaying the prefix [seq 0..${e.endSeq}] (${e.sliceLineCount} lines, session ${t}\u2026) through ${e.detectorVersion} must produce zero findings for '${e.patternId}' with the fingerprint at generation time. `+n}function l3(e,t){let n=lv.parse(e),r=Ii();yv(r)||n3(r,{recursive:!0});let o=iI(n.evalCaseId),i=sI(n.evalCaseId),s=o5(n.evalCaseId);QPe(i,t);let a=dv(r3(i));if(a!==n.replay.sliceSha256)throw new Mn(`writeEvalCase: fixture sha256 mismatch after write (expected ${n.replay.sliceSha256}, got ${a}, path ${i})`,"fixture-mismatch");return Ze(o,JSON.stringify(n,null,2),438),Ze(s,bv(n),438),XPe({timestamp:new Date().toISOString(),event:"created",evalCaseId:n.evalCaseId,cardSlug:n.cardSlug,proposalId:n.proposalId,kind:n.kind}),{evalCaseId:n.evalCaseId,jsonPath:o,fixturePath:i,markdownPath:s}}function bv(e){let t=[];if(t.push(`# ${e.evalCaseId} \u2014 \`${e.kind}\` \u2014 \`${e.status}\``),t.push(""),t.push(e.title),t.push(""),t.push(`**Card:** \`${e.cardSlug}\` \xB7 **Proposal:** ${e.proposalId?`\`${e.proposalId}\``:"_(none)_"} \xB7 **Created:** ${e.createdAt}`),t.push(""),t.push("> **How to run this.** This file is a CONTRACT; the fixture"),t.push("> beside it is the executable input. Run it with"),t.push("> `afk improve eval-run "+e.evalCaseId+"`."),t.push("> "+hI(e.assertion.patternId)),t.push(""),t.push("## Replay fixture"),t.push(""),t.push(`- **Source session:** \`${e.replay.sourceSessionId}\``),t.push(`- **Source trace:** \`${e.replay.sourceTracePath}\``),t.push(`- **Fixture:** \`${e.replay.fixturePath}\``),t.push(`- **Evidence row:** index ${e.replay.evidenceRowIndex} (seqs ${e.replay.evidenceEventIndices.join(", ")})`),t.push(`- **Slice:** lines ${e.replay.sliceLineRange.startLine}\u2013${e.replay.sliceLineRange.endLine} (${e.replay.sliceLineCount} lines)`),t.push(`- **SHA-256:** \`${e.replay.sliceSha256}\``),t.push(""),t.push("## Assertion"),t.push(""),t.push(`- **Kind:** \`${e.assertion.kind}\``),t.push(`- **Pattern:** \`${e.assertion.patternId}\``),t.push(`- **Detector:** \`${e.assertion.detectorVersion}\``),t.push(""),t.push(e.assertion.rationale),t.push(""),t.push("## Provenance"),t.push(""),t.push(`- **Detector at generation:** \`${e.provenance.detectorAtGeneration}\``),t.push(`- **Fingerprint at generation:** ${e.provenance.fingerprintAtGeneration?`\`${e.provenance.fingerprintAtGeneration}\``:"_(none \u2014 detector has no fingerprint)_"}`),t.push(`- **Card occurrence count at generation:** ${e.provenance.cardOccurrenceCountAtGeneration}`),t.push(`- **Card lastSeen at generation:** ${e.provenance.cardLastSeenAtGeneration}`),t.push(`- **Generated by:** \`${e.provenance.generatedBy}\``),t.push(""),t.push("## Triage notes"),t.push(""),e.notes.length===0)t.push("_(none)_");else for(let n of e.notes)t.push(`- _${n.at}_ \u2014 ${n.text}`);return t.push(""),t.join(`
2083
+ `)}function yI(){let e=Ii();if(!yv(e))return[];let t=[];for(let n of KPe(e)){if(!n.endsWith(".json")||n.startsWith(".")||n.endsWith(".fixture.jsonl"))continue;let r=c3(i3(e,n));r&&t.push({evalCaseId:r.evalCaseId,cardSlug:r.cardSlug,proposalId:r.proposalId,title:r.title,kind:r.kind,status:r.status,patternId:r.assertion.patternId,createdAt:r.createdAt,sliceSha256:r.replay.sliceSha256})}return t.sort((n,r)=>n.createdAt!==r.createdAt?n.createdAt<r.createdAt?1:-1:n.evalCaseId<r.evalCaseId?-1:1),t}function wm(e){return c3(iI(e))}function wv(e){return yI().filter(t=>t.cardSlug===e).map(t=>wm(t.evalCaseId)).filter(t=>t!==void 0)}function c3(e){if(yv(e))try{let t=r3(e,"utf-8"),n=JSON.parse(t),r=lv.safeParse(n);return r.success?r.data:void 0}catch{return}}function XPe(e){let t=b5.parse(e),n=r5(),r=Ii();yv(r)||n3(r,{recursive:!0});try{o3(n,JSON.stringify(t)+`
2084
2084
  `,{flag:"a"})}catch{}}function QPe(e,t){let n=`${e}.tmp-${process.pid}-${Date.now()}`;o3(n,t),GPe(n,e)}var Sm=Pi.options;function ZPe(e,t){return e.find(n=>n.replay.evidenceRowIndex===t)}var bI=["draft","approved","rejected","superseded"];function u3(e){e.command("eval-gen <cardSlug>").description("Generate a replay-mode eval-case from a failure card. Slices a byte-identical fixture from the source witness trace.").option("--proposal <id>","Back-reference to a proposal (validated to exist). Sprint 3 does NOT mutate the proposal artifact.").option("--evidence-row <index>","0-based index into the card's evidence array. Default: the most recent row (length - 1).").option("--id <override>","Override the auto-generated eval-case id").option("--json","Emit the eval-case JSON to stdout (still writes to disk)",!1).option("--no-write","Render the eval-case without persisting to disk (preview mode). Still reads the source trace.").option("--force","Write even if this card already has an eval-case (default: refuse)",!1).action((t,n)=>{try{let r=Jc(t);if(r||(console.error(`Card not found: ${t}`),process.exit(1)),n.proposal!==void 0){let c=ym(n.proposal);c||(console.error(`Proposal not found: ${n.proposal}`),process.exit(1)),c.cardSlug!==t&&(console.error(`Proposal ${n.proposal} targets card '${c.cardSlug}', not '${t}'.`),process.exit(2))}let o=r.evidence.length-1;if(n.evidenceRow!==void 0){let c=Number.parseInt(n.evidenceRow,10);(!Number.isFinite(c)||c<0)&&(console.error(`Invalid --evidence-row: '${n.evidenceRow}' (must be non-negative integer)`),process.exit(2)),o=c}if(n.write!==!1&&!n.force){let c=ZPe(wv(t),o);c&&(console.error(`Card '${t}' already has an eval-case for evidence row ${o}:
2085
2085
  ${c.evalCaseId}
2086
- Re-run with --force to regenerate that row, target a different row with --evidence-row <n>, or --no-write to preview. Run the existing one: 'afk improve eval-run ${c.evalCaseId}'.`),process.exit(1))}let i=n.id??s3(t),{evalCase:s,sliceBytes:a}=a3(r,{evalCaseId:i,evidenceRowIndex:o,proposalId:n.proposal??null});if(n.write===!1){n.json?console.log(JSON.stringify(s,null,2)):(console.log("(preview \u2014 not persisted; remove --no-write to save)"),console.log(""),console.log(bv(s)),console.log(""),console.log(`Fixture would be ${a.length} bytes, ${s.replay.sliceLineCount} lines.`));return}let l=l3(s,a);if(n.json){console.log(JSON.stringify({...s,_paths:l},null,2));return}console.log(`Wrote eval-case: ${l.evalCaseId}`),console.log(` json: ${l.jsonPath}`),console.log(` fixture: ${l.fixturePath}`),console.log(` md: ${l.markdownPath}`),console.log(` pattern: ${s.assertion.patternId} \xB7 slice: lines ${s.replay.sliceLineRange.startLine}\u2013${s.replay.sliceLineRange.endLine} (${s.replay.sliceLineCount} lines) \xB7 sha256 ${s.replay.sliceSha256.slice(0,12)}\u2026`),s.proposalId&&console.log(` proposal: ${s.proposalId} (back-reference only \u2014 Sprint 3 does not back-fill validationPlan.evalCases)`)}catch(r){if(r instanceof Mn){console.error(`eval-gen failed [${r.code}]: ${r.message}`);let o=r.code==="evidence-row-out-of-range"||r.code==="unsupported-window"?2:1;process.exit(o)}J(r)}})}function d3(e){let t=e.command("eval-cases").description("Inspect replay-mode eval-cases on disk");t.command("list").description("List all eval-cases, newest first").option("--card <slug>","Filter by card slug").option("--pattern <name>",`Filter by pattern (one of: ${Sm.join(", ")})`).option("--status <state>",`Filter by status (one of: ${bI.join(", ")})`).option("--json","Emit JSON instead of a table",!1).action(n=>{try{n.pattern&&!Sm.includes(n.pattern)&&(console.error(`Invalid --pattern: '${n.pattern}'. Must be one of: ${Sm.join(", ")}`),process.exit(2)),n.status&&!bI.includes(n.status)&&(console.error(`Invalid --status: '${n.status}'. Must be one of: ${bI.join(", ")}`),process.exit(2));let r=yI();if(n.card&&(r=r.filter(s=>s.cardSlug===n.card)),n.pattern&&(r=r.filter(s=>s.patternId===n.pattern)),n.status&&(r=r.filter(s=>s.status===n.status)),n.json){console.log(JSON.stringify(r,null,2));return}if(r.length===0){console.log("No eval-cases found.");return}let o="EVAL CASE ID | CARD | PATTERN | STATUS | CREATED",i="-".repeat(o.length);console.log(o),console.log(i);for(let s of r)console.log([s.evalCaseId.padEnd(70).slice(0,70),s.cardSlug.padEnd(44).slice(0,44),s.patternId.padEnd(20),s.status.padEnd(9),s.createdAt].join(" | "))}catch(r){J(r)}}),t.command("show <id>").description("Print an eval-case by id").option("--json","Emit raw JSON instead of rendered markdown",!1).action((n,r)=>{try{let o=wm(n);if(o||(console.error(`Eval-case not found: ${n}`),process.exit(1)),r.json){console.log(JSON.stringify(o,null,2));return}console.log(bv(o))}catch(o){J(o)}})}import{randomBytes as eMe}from"crypto";import{existsSync as SI,mkdirSync as p3,readFileSync as tMe,readdirSync as fOt,writeFileSync as nMe}from"fs";import{join as rMe}from"path";G();zr();var oMe="eval-run@v1";function m3(e,t={}){let n=(t.now??(()=>new Date))(),r=iMe(n),o=t.randomSuffix!==void 0?t.randomSuffix():eMe(3).toString("hex");if(!/^[0-9a-f]{6}$/.test(o))throw new Error(`generateEvalRunId: randomSuffix must be 6 lowercase hex chars (got '${o}')`);return`${e}-run-${r}-${o}`}function iMe(e){let t=e.getUTCFullYear(),n=String(e.getUTCMonth()+1).padStart(2,"0"),r=String(e.getUTCDate()).padStart(2,"0");return`${t}${n}${r}`}async function f3(e,t){let r=(t.now??(()=>new Date))().toISOString(),o=t.clockMs??(()=>Date.now()),i=o(),s=[],a=[],l=[],c=aMe(e,t);s.push(c.check),c.evidence&&a.push(c.evidence);let u=mv(e.assertion.patternId),d=null,p=!1;if(!u)l.push({at:r,text:`No deterministic validation contract is registered for pattern '${e.assertion.patternId}'. Supported: ${J6().join(", ")}.`});else{d=u.id;try{let S=await u.run();s.push(...S.checks),a.push(...S.evidence)}catch(S){p=!0;let E=S instanceof Error?S.message:String(S);l.push({at:r,text:`Contract '${u.id}' threw during execution: ${cn(E)}`})}}let f=hv(e.assertion.patternId),g=!1;if(f&&c.bytes!==void 0&&c.check.status==="pass")try{let S=await f.run(e,c.bytes,{...t.driveLoop?{driveLoop:t.driveLoop}:{}});s.push(...S.checks),a.push(...S.evidence),g=!0}catch(S){p=!0;let E=S instanceof Error?S.message:String(S);l.push({at:r,text:`Fixture-replay for '${e.assertion.patternId}' threw during execution: ${cn(E)}`})}let h=s.some(S=>gI(S.name)),y=f!==void 0&&c.check.status==="pass"&&g&&!h,b=sMe({hasContract:u!==void 0||g,contractThrew:p,checks:s,replayInconclusive:y}),w=Math.max(0,Math.round(o()-i)),k={schemaVersion:1,evalRunId:t.evalRunId,evalCaseId:e.evalCaseId,cardSlug:e.cardSlug,patternId:e.assertion.patternId,contract:d,status:b,createdAt:r,durationMs:w,checks:s,evidence:a,runner:{version:oMe,mode:"deterministic"},notes:l};return cI.parse(k),k}function sMe(e){return e.contractThrew?"error":e.checks.some(t=>t.status==="fail")?"fail":!e.hasContract||e.replayInconclusive===!0?"unsupported":"pass"}function aMe(e,t){let r=(t.resolveFixtureAbsPath??(u=>rMe(ve(),u)))(e.replay.fixturePath),o=e.replay.sliceSha256,i="fixture-integrity",s="Committed replay fixture exists and matches the eval-case's recorded sha256";if(!SI(r))return{check:_e({name:i,description:s,pass:!1,expected:`fixture present at ${e.replay.fixturePath}`,actual:"fixture file not found on disk"})};let a;try{a=tMe(r)}catch(u){let d=u instanceof Error?u.message:String(u);return{check:_e({name:i,description:s,pass:!1,expected:`readable fixture (${o})`,actual:`read error: ${cn(d)}`})}}let l=dv(a),c=l===o;return{check:_e({name:i,description:s,pass:c,expected:o,actual:l}),evidence:{kind:"fixture",ref:e.replay.fixturePath,detail:`sha256 ${c?"match":"MISMATCH"} (${e.replay.sliceLineCount} lines)`},bytes:a}}function g3(e){let t=cI.parse(e),n=Wc();SI(n)||p3(n,{recursive:!0});let r=s6(t.evalRunId),o=a6(t.evalRunId);return Ze(r,JSON.stringify(t,null,2),438),Ze(o,vI(t),438),uMe({timestamp:new Date().toISOString(),event:"created",evalRunId:t.evalRunId,evalCaseId:t.evalCaseId,cardSlug:t.cardSlug,patternId:t.patternId,contract:t.contract,status:t.status}),{evalRunId:t.evalRunId,jsonPath:r,markdownPath:o}}var lMe={pass:"\u2713 PASS",fail:"\u2717 FAIL",unsupported:"\u2013 UNSUPPORTED",error:"\u26A0 ERROR"},cMe={pass:"\u2713",fail:"\u2717",skipped:"\u2013"};function vI(e){let t=e.checks.filter(s=>s.status==="pass").length,n=e.checks.filter(s=>s.status==="fail").length,r=e.checks.filter(s=>s.status==="skipped").length,o=[];if(o.push(`# ${e.evalRunId} \u2014 \`eval-run\` \u2014 \`${e.status}\``),o.push(""),o.push(`Deterministic guardrail validation of eval-case \`${e.evalCaseId}\`.`),o.push(""),o.push(`**Eval-case:** \`${e.evalCaseId}\` \xB7 **Card:** \`${e.cardSlug}\` \xB7 **Pattern:** \`${e.patternId}\` \xB7 **Contract:** ${e.contract?`\`${e.contract}\``:"_(none)_"} \xB7 **Created:** ${e.createdAt} \xB7 **Duration:** ${e.durationMs}ms`),o.push(""),e.checks.some(s=>gI(s.name))?(o.push("> **What this is.** A deterministic validation of pattern"),o.push(`> \`${e.patternId}\`. It re-drove the failure recorded in the committed`),o.push("> fixture through the LIVE guardrail and asserts the recorded failure is"),o.push("> neutralised at the recorded magnitude \u2014 proving the behaviour is fixed,"),o.push("> not merely that a guardrail exists. It re-drives the recorded failure"),o.push("> conditions; it does NOT re-execute the original tool/LLM.")):(o.push("> **What this is.** A narrow, deterministic check that the guardrail"),o.push(`> mapped to pattern \`${e.patternId}\` is present and behaving. It`),o.push("> validates the guardrail the pattern maps to; the eval-case's own"),o.push("> `pattern-absent` assertion remains the full contract.")),o.push(""),o.push(`## Result: ${lMe[e.status]} (${t}/${e.checks.length} checks passed${n?`, ${n} failed`:""}${r?`, ${r} skipped`:""})`),o.push(""),o.push("## Checks"),o.push(""),e.checks.length===0)o.push("_(none)_");else{o.push("| Check | Status | Expected | Actual |"),o.push("|---|---|---|---|");for(let s of e.checks)o.push(`| ${wI(s.name)} | ${cMe[s.status]} ${s.status} | ${wI(s.expected)} | ${wI(s.actual)} |`)}if(o.push(""),o.push("## Evidence"),o.push(""),e.evidence.length===0)o.push("_(none)_");else for(let s of e.evidence)o.push(`- **[${s.kind}]** \`${s.ref}\` \u2014 ${s.detail}`);if(o.push(""),o.push("## Runner"),o.push(""),o.push(`- **Version:** \`${e.runner.version}\` \xB7 **Mode:** \`${e.runner.mode}\``),o.push(""),o.push("## Notes"),o.push(""),e.notes.length===0)o.push("_(none)_");else for(let s of e.notes)o.push(`- _${s.at}_ \u2014 ${s.text}`);return o.push(""),o.join(`
2087
- `)}function wI(e){return e.replace(/\|/g,"\\|").replace(/\n/g," ")}function uMe(e){let t=S6.parse(e),n=Wc();SI(n)||p3(n,{recursive:!0});try{nMe(i6(),JSON.stringify(t)+`
2086
+ Re-run with --force to regenerate that row, target a different row with --evidence-row <n>, or --no-write to preview. Run the existing one: 'afk improve eval-run ${c.evalCaseId}'.`),process.exit(1))}let i=n.id??s3(t),{evalCase:s,sliceBytes:a}=a3(r,{evalCaseId:i,evidenceRowIndex:o,proposalId:n.proposal??null});if(n.write===!1){n.json?console.log(JSON.stringify(s,null,2)):(console.log("(preview \u2014 not persisted; remove --no-write to save)"),console.log(""),console.log(bv(s)),console.log(""),console.log(`Fixture would be ${a.length} bytes, ${s.replay.sliceLineCount} lines.`));return}let l=l3(s,a);if(n.json){console.log(JSON.stringify({...s,_paths:l},null,2));return}console.log(`Wrote eval-case: ${l.evalCaseId}`),console.log(` json: ${l.jsonPath}`),console.log(` fixture: ${l.fixturePath}`),console.log(` md: ${l.markdownPath}`),console.log(` pattern: ${s.assertion.patternId} \xB7 slice: lines ${s.replay.sliceLineRange.startLine}\u2013${s.replay.sliceLineRange.endLine} (${s.replay.sliceLineCount} lines) \xB7 sha256 ${s.replay.sliceSha256.slice(0,12)}\u2026`),s.proposalId&&console.log(` proposal: ${s.proposalId} (back-reference only \u2014 Sprint 3 does not back-fill validationPlan.evalCases)`)}catch(r){if(r instanceof Mn){console.error(`eval-gen failed [${r.code}]: ${r.message}`);let o=r.code==="evidence-row-out-of-range"||r.code==="unsupported-window"?2:1;process.exit(o)}J(r)}})}function d3(e){let t=e.command("eval-cases").description("Inspect replay-mode eval-cases on disk");t.command("list").description("List all eval-cases, newest first").option("--card <slug>","Filter by card slug").option("--pattern <name>",`Filter by pattern (one of: ${Sm.join(", ")})`).option("--status <state>",`Filter by status (one of: ${bI.join(", ")})`).option("--json","Emit JSON instead of a table",!1).action(n=>{try{n.pattern&&!Sm.includes(n.pattern)&&(console.error(`Invalid --pattern: '${n.pattern}'. Must be one of: ${Sm.join(", ")}`),process.exit(2)),n.status&&!bI.includes(n.status)&&(console.error(`Invalid --status: '${n.status}'. Must be one of: ${bI.join(", ")}`),process.exit(2));let r=yI();if(n.card&&(r=r.filter(s=>s.cardSlug===n.card)),n.pattern&&(r=r.filter(s=>s.patternId===n.pattern)),n.status&&(r=r.filter(s=>s.status===n.status)),n.json){console.log(JSON.stringify(r,null,2));return}if(r.length===0){console.log("No eval-cases found.");return}let o="EVAL CASE ID | CARD | PATTERN | STATUS | CREATED",i="-".repeat(o.length);console.log(o),console.log(i);for(let s of r)console.log([s.evalCaseId.padEnd(70).slice(0,70),s.cardSlug.padEnd(44).slice(0,44),s.patternId.padEnd(20),s.status.padEnd(9),s.createdAt].join(" | "))}catch(r){J(r)}}),t.command("show <id>").description("Print an eval-case by id").option("--json","Emit raw JSON instead of rendered markdown",!1).action((n,r)=>{try{let o=wm(n);if(o||(console.error(`Eval-case not found: ${n}`),process.exit(1)),r.json){console.log(JSON.stringify(o,null,2));return}console.log(bv(o))}catch(o){J(o)}})}import{randomBytes as eMe}from"crypto";import{existsSync as SI,mkdirSync as p3,readFileSync as tMe,readdirSync as fOt,writeFileSync as nMe}from"fs";import{join as rMe}from"path";G();zr();var oMe="eval-run@v1";function m3(e,t={}){let n=(t.now??(()=>new Date))(),r=iMe(n),o=t.randomSuffix!==void 0?t.randomSuffix():eMe(3).toString("hex");if(!/^[0-9a-f]{6}$/.test(o))throw new Error(`generateEvalRunId: randomSuffix must be 6 lowercase hex chars (got '${o}')`);return`${e}-run-${r}-${o}`}function iMe(e){let t=e.getUTCFullYear(),n=String(e.getUTCMonth()+1).padStart(2,"0"),r=String(e.getUTCDate()).padStart(2,"0");return`${t}${n}${r}`}async function f3(e,t){let r=(t.now??(()=>new Date))().toISOString(),o=t.clockMs??(()=>Date.now()),i=o(),s=[],a=[],l=[],c=aMe(e,t);s.push(c.check),c.evidence&&a.push(c.evidence);let u=mv(e.assertion.patternId),d=null,p=!1;if(!u)l.push({at:r,text:`No deterministic validation contract is registered for pattern '${e.assertion.patternId}'. Supported: ${J5().join(", ")}.`});else{d=u.id;try{let S=await u.run();s.push(...S.checks),a.push(...S.evidence)}catch(S){p=!0;let E=S instanceof Error?S.message:String(S);l.push({at:r,text:`Contract '${u.id}' threw during execution: ${cn(E)}`})}}let f=hv(e.assertion.patternId),g=!1;if(f&&c.bytes!==void 0&&c.check.status==="pass")try{let S=await f.run(e,c.bytes,{...t.driveLoop?{driveLoop:t.driveLoop}:{}});s.push(...S.checks),a.push(...S.evidence),g=!0}catch(S){p=!0;let E=S instanceof Error?S.message:String(S);l.push({at:r,text:`Fixture-replay for '${e.assertion.patternId}' threw during execution: ${cn(E)}`})}let h=s.some(S=>gI(S.name)),y=f!==void 0&&c.check.status==="pass"&&g&&!h,b=sMe({hasContract:u!==void 0||g,contractThrew:p,checks:s,replayInconclusive:y}),w=Math.max(0,Math.round(o()-i)),k={schemaVersion:1,evalRunId:t.evalRunId,evalCaseId:e.evalCaseId,cardSlug:e.cardSlug,patternId:e.assertion.patternId,contract:d,status:b,createdAt:r,durationMs:w,checks:s,evidence:a,runner:{version:oMe,mode:"deterministic"},notes:l};return cI.parse(k),k}function sMe(e){return e.contractThrew?"error":e.checks.some(t=>t.status==="fail")?"fail":!e.hasContract||e.replayInconclusive===!0?"unsupported":"pass"}function aMe(e,t){let r=(t.resolveFixtureAbsPath??(u=>rMe(ve(),u)))(e.replay.fixturePath),o=e.replay.sliceSha256,i="fixture-integrity",s="Committed replay fixture exists and matches the eval-case's recorded sha256";if(!SI(r))return{check:_e({name:i,description:s,pass:!1,expected:`fixture present at ${e.replay.fixturePath}`,actual:"fixture file not found on disk"})};let a;try{a=tMe(r)}catch(u){let d=u instanceof Error?u.message:String(u);return{check:_e({name:i,description:s,pass:!1,expected:`readable fixture (${o})`,actual:`read error: ${cn(d)}`})}}let l=dv(a),c=l===o;return{check:_e({name:i,description:s,pass:c,expected:o,actual:l}),evidence:{kind:"fixture",ref:e.replay.fixturePath,detail:`sha256 ${c?"match":"MISMATCH"} (${e.replay.sliceLineCount} lines)`},bytes:a}}function g3(e){let t=cI.parse(e),n=Wc();SI(n)||p3(n,{recursive:!0});let r=s5(t.evalRunId),o=a5(t.evalRunId);return Ze(r,JSON.stringify(t,null,2),438),Ze(o,vI(t),438),uMe({timestamp:new Date().toISOString(),event:"created",evalRunId:t.evalRunId,evalCaseId:t.evalCaseId,cardSlug:t.cardSlug,patternId:t.patternId,contract:t.contract,status:t.status}),{evalRunId:t.evalRunId,jsonPath:r,markdownPath:o}}var lMe={pass:"\u2713 PASS",fail:"\u2717 FAIL",unsupported:"\u2013 UNSUPPORTED",error:"\u26A0 ERROR"},cMe={pass:"\u2713",fail:"\u2717",skipped:"\u2013"};function vI(e){let t=e.checks.filter(s=>s.status==="pass").length,n=e.checks.filter(s=>s.status==="fail").length,r=e.checks.filter(s=>s.status==="skipped").length,o=[];if(o.push(`# ${e.evalRunId} \u2014 \`eval-run\` \u2014 \`${e.status}\``),o.push(""),o.push(`Deterministic guardrail validation of eval-case \`${e.evalCaseId}\`.`),o.push(""),o.push(`**Eval-case:** \`${e.evalCaseId}\` \xB7 **Card:** \`${e.cardSlug}\` \xB7 **Pattern:** \`${e.patternId}\` \xB7 **Contract:** ${e.contract?`\`${e.contract}\``:"_(none)_"} \xB7 **Created:** ${e.createdAt} \xB7 **Duration:** ${e.durationMs}ms`),o.push(""),e.checks.some(s=>gI(s.name))?(o.push("> **What this is.** A deterministic validation of pattern"),o.push(`> \`${e.patternId}\`. It re-drove the failure recorded in the committed`),o.push("> fixture through the LIVE guardrail and asserts the recorded failure is"),o.push("> neutralised at the recorded magnitude \u2014 proving the behaviour is fixed,"),o.push("> not merely that a guardrail exists. It re-drives the recorded failure"),o.push("> conditions; it does NOT re-execute the original tool/LLM.")):(o.push("> **What this is.** A narrow, deterministic check that the guardrail"),o.push(`> mapped to pattern \`${e.patternId}\` is present and behaving. It`),o.push("> validates the guardrail the pattern maps to; the eval-case's own"),o.push("> `pattern-absent` assertion remains the full contract.")),o.push(""),o.push(`## Result: ${lMe[e.status]} (${t}/${e.checks.length} checks passed${n?`, ${n} failed`:""}${r?`, ${r} skipped`:""})`),o.push(""),o.push("## Checks"),o.push(""),e.checks.length===0)o.push("_(none)_");else{o.push("| Check | Status | Expected | Actual |"),o.push("|---|---|---|---|");for(let s of e.checks)o.push(`| ${wI(s.name)} | ${cMe[s.status]} ${s.status} | ${wI(s.expected)} | ${wI(s.actual)} |`)}if(o.push(""),o.push("## Evidence"),o.push(""),e.evidence.length===0)o.push("_(none)_");else for(let s of e.evidence)o.push(`- **[${s.kind}]** \`${s.ref}\` \u2014 ${s.detail}`);if(o.push(""),o.push("## Runner"),o.push(""),o.push(`- **Version:** \`${e.runner.version}\` \xB7 **Mode:** \`${e.runner.mode}\``),o.push(""),o.push("## Notes"),o.push(""),e.notes.length===0)o.push("_(none)_");else for(let s of e.notes)o.push(`- _${s.at}_ \u2014 ${s.text}`);return o.push(""),o.join(`
2087
+ `)}function wI(e){return e.replace(/\|/g,"\\|").replace(/\n/g," ")}function uMe(e){let t=S5.parse(e),n=Wc();SI(n)||p3(n,{recursive:!0});try{nMe(i5(),JSON.stringify(t)+`
2088
2088
  `,{flag:"a"})}catch{}}function h3(e){e.command("eval-run <evalCaseIdOrCardSlug>").description(`Run the smallest deterministic validation contract for an eval-case's pattern.
2089
- Validates guardrails (no LLM, no patch/apply). Known contracts: ${V6().join(", ")}.`).option("--id <override>","Override the auto-generated eval-run id").option("--json","Emit the eval-run JSON to stdout (still writes to disk)",!1).option("--no-write","Run and render without persisting to disk (preview mode)").action(async(t,n)=>{try{let r=wm(t);r||(r=wv(t)[0]),r||(console.error(`No eval-case found for '${t}'. Pass an eval-case id (see 'afk improve eval-cases list') or a card slug with at least one generated eval-case ('afk improve eval-gen <slug>').`),process.exit(1));let o=n.id??m3(r.cardSlug),i=await f3(r,{evalRunId:o});if(n.write===!1){n.json?console.log(JSON.stringify(i,null,2)):(console.log("(preview \u2014 not persisted; remove --no-write to save)"),console.log(""),console.log(vI(i))),Sv(i.status);return}let s=g3(i);if(n.json){console.log(JSON.stringify({...i,_paths:s},null,2)),Sv(i.status);return}dMe(i,s.jsonPath,s.markdownPath),Sv(i.status)}catch(r){J(r)}})}function dMe(e,t,n){let r=e.checks.filter(s=>s.status==="pass").length,o=e.checks.filter(s=>s.status==="fail").length,i=e.checks.filter(s=>s.status==="skipped").length;console.log(`Ran eval-run: ${e.evalRunId} [${e.status.toUpperCase()}]`),console.log(` json: ${t}`),console.log(` md: ${n}`),console.log(` eval-case: ${e.evalCaseId} \xB7 card: ${e.cardSlug} \xB7 pattern: ${e.patternId} \xB7 contract: ${e.contract??"(none)"}`),console.log(` checks: ${r} passed${o?`, ${o} failed`:""}${i?`, ${i} skipped`:""} (${e.checks.length} total)`);for(let s of e.checks){let a=s.status==="pass"?"\u2713":s.status==="fail"?"\u2717":"\u2013";console.log(` ${a} ${s.name}`)}for(let s of e.notes)console.log(` note: ${s.text}`)}function Sv(e){e==="fail"||e==="error"?process.exitCode=1:e==="unsupported"&&(process.exitCode=3)}function y3(e){let t=e.command("improve").description("Self-improvement pipeline: scan traces, triage cards, draft proposals, generate replay eval-cases.");M6(t),$6(t),H6(t),W6(t),u3(t),d3(t),h3(t)}uT();G();me();import pMe from"better-sqlite3";import{chmodSync as mMe,existsSync as fMe,mkdirSync as gMe,readdirSync as hMe,readFileSync as yMe}from"fs";import{join as vv,basename as bMe}from"path";var b3="index.db",wMe="transcripts-index",kI=1,SMe=`
2089
+ Validates guardrails (no LLM, no patch/apply). Known contracts: ${V5().join(", ")}.`).option("--id <override>","Override the auto-generated eval-run id").option("--json","Emit the eval-run JSON to stdout (still writes to disk)",!1).option("--no-write","Run and render without persisting to disk (preview mode)").action(async(t,n)=>{try{let r=wm(t);r||(r=wv(t)[0]),r||(console.error(`No eval-case found for '${t}'. Pass an eval-case id (see 'afk improve eval-cases list') or a card slug with at least one generated eval-case ('afk improve eval-gen <slug>').`),process.exit(1));let o=n.id??m3(r.cardSlug),i=await f3(r,{evalRunId:o});if(n.write===!1){n.json?console.log(JSON.stringify(i,null,2)):(console.log("(preview \u2014 not persisted; remove --no-write to save)"),console.log(""),console.log(vI(i))),Sv(i.status);return}let s=g3(i);if(n.json){console.log(JSON.stringify({...i,_paths:s},null,2)),Sv(i.status);return}dMe(i,s.jsonPath,s.markdownPath),Sv(i.status)}catch(r){J(r)}})}function dMe(e,t,n){let r=e.checks.filter(s=>s.status==="pass").length,o=e.checks.filter(s=>s.status==="fail").length,i=e.checks.filter(s=>s.status==="skipped").length;console.log(`Ran eval-run: ${e.evalRunId} [${e.status.toUpperCase()}]`),console.log(` json: ${t}`),console.log(` md: ${n}`),console.log(` eval-case: ${e.evalCaseId} \xB7 card: ${e.cardSlug} \xB7 pattern: ${e.patternId} \xB7 contract: ${e.contract??"(none)"}`),console.log(` checks: ${r} passed${o?`, ${o} failed`:""}${i?`, ${i} skipped`:""} (${e.checks.length} total)`);for(let s of e.checks){let a=s.status==="pass"?"\u2713":s.status==="fail"?"\u2717":"\u2013";console.log(` ${a} ${s.name}`)}for(let s of e.notes)console.log(` note: ${s.text}`)}function Sv(e){e==="fail"||e==="error"?process.exitCode=1:e==="unsupported"&&(process.exitCode=3)}function y3(e){let t=e.command("improve").description("Self-improvement pipeline: scan traces, triage cards, draft proposals, generate replay eval-cases.");M5(t),$5(t),H5(t),W5(t),u3(t),d3(t),h3(t)}uT();G();me();import pMe from"better-sqlite3";import{chmodSync as mMe,existsSync as fMe,mkdirSync as gMe,readdirSync as hMe,readFileSync as yMe}from"fs";import{join as vv,basename as bMe}from"path";var b3="index.db",wMe="transcripts-index",kI=1,SMe=`
2090
2090
  CREATE TABLE IF NOT EXISTS transcripts (
2091
2091
  id INTEGER PRIMARY KEY AUTOINCREMENT,
2092
2092
  -- filename is the stable key: ISO timestamp with ':' and '.' \u2192 '-'.
@@ -2281,7 +2281,7 @@ Safe to run repeatedly \u2014 replaces the index atomically.`).action(async()=>{
2281
2281
  </main>
2282
2282
  </body>
2283
2283
  </html>`}function M3(e){e.command("insights").description("Generate a local usage analytics report from AFK telemetry").option("--days <n>","Lookback window in days","30").option("--output <path>","Output file path for the HTML report").option("--no-open","Do not open the report in a browser after generation").action(async t=>{try{let n=Math.max(1,parseInt(t.days,10)||30),r=ya(),o=t.output??i0e(r,"insights.html");r0e(o0e(o),{recursive:!0});let i=await A3({days:n}),s=_3(i),a=P3(i,s,{days:n});n0e(o,a,"utf-8"),process.stdout.write(`\u2713 Insights report written to ${o}
2284
- `),t.open!==!1&&IS(o)}catch(n){J(n)}})}wt();Ne();nt();nt();import{realpathSync as u0e}from"fs";$I();$I({path:It(),override:!1});process.argv.includes("shell-init")||rP();process.env.AFK_FRAMEWORK_DIR??=Tt();process.env.AGENT_SURFACE??="afk";sP();or(ir(Eo(T.AFK_THEME)));var Ae=new s0e;Ae.name("afk").description("AI agent CLI. Starts interactive REPL by default; use `afk chat` for one-shot.").version(Pr()).option("--no-update-check","Skip update version check");QK(Ae);b4(Ae);G4(Ae);S8(Ae);v8(Ae);f4(Ae);T8(Ae);x8(Ae);C8(Ae);g4(Ae);I8(Ae);P8(Ae);M8(Ae);O8(Ae);W8(Ae);o5(Ae);a5(Ae);l5(Ae);c5(Ae);m5(Ae);b5(Ae);G5(Ae);Q5(Ae);y3(Ae);dO(Ae);S3(Ae);M3(Ae);Ae.commands.find(e=>e.name()==="chat")?.alias("c");Ae.commands.find(e=>e.name()==="interactive")?.alias("i");Ae.commands.find(e=>e.name()==="status")?.alias("s");Ae.addHelpText("after",`
2284
+ `),t.open!==!1&&IS(o)}catch(n){J(n)}})}wt();Ne();nt();nt();import{realpathSync as u0e}from"fs";$I();$I({path:It(),override:!1});process.argv.includes("shell-init")||rP();process.env.AFK_FRAMEWORK_DIR??=Tt();process.env.AGENT_SURFACE??="afk";sP();or(ir(Eo(T.AFK_THEME)));var Ae=new s0e;Ae.name("afk").description("AI agent CLI. Starts interactive REPL by default; use `afk chat` for one-shot.").version(Pr()).option("--no-update-check","Skip update version check");QK(Ae);b4(Ae);G4(Ae);S8(Ae);v8(Ae);f4(Ae);T8(Ae);x8(Ae);C8(Ae);g4(Ae);I8(Ae);P8(Ae);M8(Ae);O8(Ae);W8(Ae);o6(Ae);a6(Ae);l6(Ae);c6(Ae);m6(Ae);b6(Ae);G6(Ae);Q6(Ae);y3(Ae);dO(Ae);S3(Ae);M3(Ae);Ae.commands.find(e=>e.name()==="chat")?.alias("c");Ae.commands.find(e=>e.name()==="interactive")?.alias("i");Ae.commands.find(e=>e.name()==="status")?.alias("s");Ae.addHelpText("after",`
2285
2285
  Examples:
2286
2286
  $ afk # start interactive REPL
2287
2287
  $ afk "what does this do?" # REPL, auto-submits the prompt as the first turn