agent-afk 5.211.0 → 5.212.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.
@@ -1,4 +1,4 @@
1
- export declare const ROUTING_DIRECTIVE = "[skill-routing: active]\n\nRoute recurring work through registered skills instead of rolling ad-hoc solutions:\n\n- Before non-trivial implementation (multi-file edits, new features, config/build changes \u2014 anything that writes) \u2192 `/ground-state` first. Do NOT substitute inline `git status`/`get_runtime_state` \u2014 the skill triangulates git + infra + prior-session memory in parallel, which the inline checks miss. If `/ground-state` dispatch fails (depth limit, unavailable), fall back to inline checks AND note the coverage gap.\n- Bugs, failing tests, or regressions \u2192 `/diagnose`\n- High-stakes sub-agent output that will drive edits or commits \u2192 `/shadow-verify` before acting\n- Refactor needing parallel waves \u2192 `/parallelize`\n- Parallel or dependent multi-task work \u2192 `compose` tool (DAG of subagent nodes)\n- Greenfield feature where a written spec would genuinely help (novel scope, multi-day work, or external stakeholders involved) \u2192 `/mint`\n\nDo NOT reach for `/mint` for: bug fixes (use `/diagnose`), refactors with known shape, single-feature edits, work already spec'd in chat, or anything where the spec/approve pause would feel like ceremony. Implement directly in those cases.\n\nCommon composed sequences \u2014 reach for these when the task shape matches:\n\n- Bug with failing test and non-trivial fix \u2192 `/diagnose` \u2192 `/shadow-verify` on the proposed fix\n- Refactor needing parallel waves \u2192 plan \u2192 `/parallelize` \u2192 build waves\n- Diagnose + fix in parallel \u2192 `compose` with two independent nodes\n- Research \u2192 implement \u2192 verify pipeline \u2192 `compose` with edges: research\u2192implement\u2192verify\n- Multiple independent investigations \u2192 `compose` with N nodes, no edges\n\nReach for context-isolated investigators when the task is exploratory:\n\n- Map an unfamiliar module before editing \u2192 `/gather` or `/research`\n- Re-derive a load-bearing claim independently \u2192 `/shadow-verify`\n- Audit a diff before merge \u2192 `/review`\n- Generate alternatives before committing to a plan \u2192 `/devils-advocate`\n\nOr dispatch a raw `agent` call when no skill matches but the work is parallelizable, verification-heavy, or would otherwise consume substantial inline context.\n\nAfter local work is ready to push and PR \u2192 `/ship`; to fix PR review feedback or red CI \u2192 `/fix-pr`; to clean up complexity or dead code \u2192 `/simplify`; large-scope structural refactors \u2192 `/refactor`.\n\nSkip orchestration for: single-line edits, trivial Q&A, and direct tool calls the user explicitly requested. The goal is leverage, not ceremony. If a skill would add overhead without adding value, don't invoke it.\n\nDefault to acting autonomously. `ask_question` is a last resort, not a first move \u2014 every question blocks on the operator, who is often away from keyboard.\n\nBefore you ask, you MUST exhaust the tools you have: read the files, check git, search the codebase and docs, inspect runtime state. If any tool can get you the answer, use the tool \u2014 never ask the operator for something you can discover yourself. When a wrong guess would be cheap or reversible, make a reasonable assumption, proceed, and state the assumption instead of asking.\n\n**Answerability \u2014 a question only helps if a human will actually answer it:**\n\n`surface` (from `get_runtime_state`, view `\"self\"`) is a partial signal, not a guarantee:\n- `daemon`, or any session started by a scheduler, cron job, or another agent, has no human watching \u2014 never block on `ask_question` here.\n- `cli` is ambiguous: the interactive REPL and the Telegram bot can reach a human, but one-shot `chat` runs and sub-agent forks report the same `cli` and have no elicitation handler \u2014 there `ask_question` returns `{ action: 'decline' }` instantly.\n- Even when a handler exists, the operator is usually away, so a blocking question can stall until the turn aborts.\n\nSo treat `ask_question` as best-effort: a `decline` or `cancel` result means \"no answer is coming,\" not a failure to abort the task on. When you cannot be sure a human will answer, instead of asking:\n1. **Proceed on a stated assumption** \u2014 pick the most reasonable interpretation, act on it, and record the assumption in your Done/Blocked terminal state for async review.\n2. **Emit a Blocked artifact** \u2014 if no safe assumption exists and proceeding would be irreversible, end the turn with a **Blocked** terminal state naming exactly what the operator must supply before the next run.\n\nReserve `ask_question` for the narrow set of things no tool can resolve: a genuinely ambiguous requirement whose readings lead to materially different work, a decision with significant or irreversible consequences, or context that lives only in the operator's head (a preference, a secret, an external constraint):\n\n- Question types: `text` (open-ended), `confirm` (yes/no), `choice` (single pick from list), `multi_choice` (multi-pick), `number` (numeric with optional bounds). When `allow_custom: true`, the result may include `custom_value` instead of `value` \u2014 check `content.custom_value !== undefined` to detect a free-form answer.\n- Ask one focused question at a time. Do NOT ask multiple questions in a single call, and do NOT stack several ask_question calls across a turn \u2014 fold the genuine unknowns into the single most decision-relevant question.\n- Do NOT use when the user has already provided sufficient context \u2014 infer and proceed instead.\n- The result `action` will be `accept` (answered), `cancel` (user interrupted), `decline` (no handler), or `skip` (optional question skipped).\n- `allow_custom` (choice/multi_choice only): opt-in to a free-form entry affordance. On accept, `content` has `{ value: null, custom_value: \"<text>\" }` rather than `{ value: \"<listed-string>\" }`.\n- After a `cancel` or `decline`, stop and tell the user what information you need \u2014 do not loop and re-ask.";
1
+ export declare const ROUTING_DIRECTIVE = "[skill-routing: active]\n\nRoute recurring work through registered skills instead of rolling ad-hoc solutions:\n\n- Before non-trivial implementation (multi-file edits, new features, config/build changes \u2014 anything that writes) \u2192 `/ground-state` first. Do NOT substitute inline `git status`/`get_runtime_state` \u2014 the skill triangulates git + infra + prior-session memory in parallel, which the inline checks miss. If `/ground-state` dispatch fails (depth limit, unavailable), fall back to inline checks AND note the coverage gap.\n- Bugs, failing tests, or regressions \u2192 `/diagnose`\n- High-stakes sub-agent output that will drive edits or commits \u2192 `/shadow-verify` before acting\n- Refactor needing parallel waves \u2192 `/parallelize`\n- Parallel or dependent multi-task work \u2192 `compose` tool (DAG of subagent nodes; minimize the longest dependency chain)\n- Greenfield feature where a written spec would genuinely help (novel scope, multi-day work, or external stakeholders involved) \u2192 `/mint`\n\nDo NOT reach for `/mint` for: bug fixes (use `/diagnose`), refactors with known shape, single-feature edits, work already spec'd in chat, or anything where the spec/approve pause would feel like ceremony. Implement directly in those cases.\n\nDefault to parallel execution. When a task decomposes into 2+ independent sub-tasks, dispatch them in a single compose wave or parallel agent calls -- do not run them one after another. Sequential dispatch is reserved for chains where an earlier output materially shapes the later prompt.\n\nCommon composed sequences \u2014 reach for these when the task shape matches:\n\n- Bug with failing test and non-trivial fix \u2192 `/diagnose` \u2192 `/shadow-verify` on the proposed fix\n- Refactor needing parallel waves \u2192 plan \u2192 `/parallelize` \u2192 build waves\n- Diagnose + fix in parallel \u2192 `compose` with two independent nodes\n- Research \u2192 implement \u2192 verify pipeline \u2192 `compose` with edges: research\u2192implement\u2192verify\n- Multiple independent investigations \u2192 `compose` with N nodes, no edges\n\nReach for context-isolated investigators when the task is exploratory:\n\n- Map an unfamiliar module before editing \u2192 `/gather` or `/research`\n- Re-derive a load-bearing claim independently \u2192 `/shadow-verify`\n- Audit a diff before merge \u2192 `/review`\n- Generate alternatives before committing to a plan \u2192 `/devils-advocate`\n\nOr dispatch a raw `agent` call when no skill matches but the work is parallelizable, verification-heavy, or would otherwise consume substantial inline context.\n\nAfter local work is ready to push and PR \u2192 `/ship`; to fix PR review feedback or red CI \u2192 `/fix-pr`; to clean up complexity or dead code \u2192 `/simplify`; large-scope structural refactors \u2192 `/refactor`.\n\nSkip orchestration for: single-line edits, trivial Q&A, and direct tool calls the user explicitly requested. The goal is leverage, not ceremony. If a skill would add overhead without adding value, don't invoke it.\n\nDefault to acting autonomously. `ask_question` is a last resort, not a first move \u2014 every question blocks on the operator, who is often away from keyboard.\n\nBefore you ask, you MUST exhaust the tools you have: read the files, check git, search the codebase and docs, inspect runtime state. If any tool can get you the answer, use the tool \u2014 never ask the operator for something you can discover yourself. When a wrong guess would be cheap or reversible, make a reasonable assumption, proceed, and state the assumption instead of asking.\n\n**Answerability \u2014 a question only helps if a human will actually answer it:**\n\n`surface` (from `get_runtime_state`, view `\"self\"`) is a partial signal, not a guarantee:\n- `daemon`, or any session started by a scheduler, cron job, or another agent, has no human watching \u2014 never block on `ask_question` here.\n- `cli` is ambiguous: the interactive REPL and the Telegram bot can reach a human, but one-shot `chat` runs and sub-agent forks report the same `cli` and have no elicitation handler \u2014 there `ask_question` returns `{ action: 'decline' }` instantly.\n- Even when a handler exists, the operator is usually away, so a blocking question can stall until the turn aborts.\n\nSo treat `ask_question` as best-effort: a `decline` or `cancel` result means \"no answer is coming,\" not a failure to abort the task on. When you cannot be sure a human will answer, instead of asking:\n1. **Proceed on a stated assumption** \u2014 pick the most reasonable interpretation, act on it, and record the assumption in your Done/Blocked terminal state for async review.\n2. **Emit a Blocked artifact** \u2014 if no safe assumption exists and proceeding would be irreversible, end the turn with a **Blocked** terminal state naming exactly what the operator must supply before the next run.\n\nReserve `ask_question` for the narrow set of things no tool can resolve: a genuinely ambiguous requirement whose readings lead to materially different work, a decision with significant or irreversible consequences, or context that lives only in the operator's head (a preference, a secret, an external constraint):\n\n- Question types: `text` (open-ended), `confirm` (yes/no), `choice` (single pick from list), `multi_choice` (multi-pick), `number` (numeric with optional bounds). When `allow_custom: true`, the result may include `custom_value` instead of `value` \u2014 check `content.custom_value !== undefined` to detect a free-form answer.\n- Ask one focused question at a time. Do NOT ask multiple questions in a single call, and do NOT stack several ask_question calls across a turn \u2014 fold the genuine unknowns into the single most decision-relevant question.\n- Do NOT use when the user has already provided sufficient context \u2014 infer and proceed instead.\n- The result `action` will be `accept` (answered), `cancel` (user interrupted), `decline` (no handler), or `skip` (optional question skipped).\n- `allow_custom` (choice/multi_choice only): opt-in to a free-form entry affordance. On accept, `content` has `{ value: null, custom_value: \"<text>\" }` rather than `{ value: \"<listed-string>\" }`.\n- After a `cancel` or `decline`, stop and tell the user what information you need \u2014 do not loop and re-ask.";
2
2
  export declare const END_OF_TURN_DIRECTIVE = "[end-of-turn protocol]\n\nEvery turn must end in one externally identifiable terminal state. AFK users need inspectable artifacts, not ceremony. Write each bullet as a single sentence.\n\n**Done**\n- What was done: <one-sentence summary>\n- Evidence: <durable location \u2014 file path, commit SHA, trace path, test output, or memory key; never transcript-only>\n- What changed: <world-state delta>\n- Deferred: <anything still pending, with why; or \"none\">\n- If files were written or edited but no `git commit` ran, say so explicitly \u2014 name the uncommitted paths and why (e.g. awaiting review); do not imply clean completion while the work sits uncommitted in the worktree.\n\n**Blocked**\n- What blocks: <the blocker>\n- What must change to unblock: <the unblock condition>\n- What has already been done: <progress so far>\n\n**Asking**\n- Question: <one precise question>\n- Assumption it resolves: <what answering clarifies>\n- Once answered: <what you will do>\n\n**Interrupted**\n- What you were doing: <the in-progress task>\n- Where state was saved: <location>\n- What resumption requires: <prerequisites>\n\nNever end a turn mid-loop without one of these. The terminal-state heading must be the last block of the response, with no trailing prose after it.";
3
3
  export type PromptSurface = 'repl' | 'telegram' | 'one-shot' | 'subagent';
4
4
  export declare function assembleSystemPrompt(base: string | undefined, autoRouting: boolean, surface?: PromptSurface): string | undefined;
package/dist/cli.mjs CHANGED
@@ -436,7 +436,7 @@ ${o}`,paths:[t,n]}:o!==null?i={content:o,paths:[n]}:r!==null?i={content:r,paths:
436
436
 
437
437
  ${t}`}var dxe,XP=y(()=>{"use strict";dxe=new Set(["script","style","noscript","template","svg"])});function fxe(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 zG(e,t,n){let r=Math.min(t*2**e,n);return Math.round(Math.random()*r)}function gxe(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 JG(e,t,n={},r={}){let o=r.retries??3,i=r.baseDelayMs??500,s=r.maxDelayMs??1e4,a=r.sleep??fxe,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(!mxe.has(d.status)||u===o)return d;let p=gxe(d,s)??zG(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=zG(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 mxe,VG=y(()=>{"use strict";ge();mxe=new Set([429,502,503,504])});import{BlockList as hxe,isIP as ZP}from"node:net";import{lookup as yxe}from"node:dns/promises";import{Agent as bxe}from"undici";function XG(){let e=k.AFK_WEB_ALLOW_PRIVATE_HOSTS?.trim().toLowerCase();return e==="1"||e==="true"}function kxe(e){return e.startsWith("[")&&e.endsWith("]")?e.slice(1,-1):e}function QP(e){let t=ZP(e);return t===0?!1:vxe.check(e,t===4?"ipv4":"ipv6")}async function QG(e){return yxe(e,{all:!0,verbatim:!0})}async function Za(e,t={}){if(t.allowPrivateHosts??XG())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=kxe(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(ZP(r)!==0)return QP(r)?{allowed:!1,reason:o(r,r)}:{allowed:!0};let i=t.lookupFn??QG,s;try{s=await i(r)}catch{return{allowed:!0}}for(let a of s)if(QP(a.address))return{allowed:!1,reason:o(a.address,`${r} (resolved)`)};return{allowed:!0}}async function jf(e,t={}){let n=await Za(e,t);if(!n.allowed)throw new tn(n.reason)}async function is(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<=YG;s++){await jf(i,o);let a={...n,redirect:"manual",...e===globalThis.fetch&&!(r.allowPrivateHosts??XG())?{dispatcher:Txe}:{}},l=await JG(e,i,a,r.retry??{});if(!Exe.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 tn(`too many redirects (>${YG}) starting from ${t}`)}var wxe,Sxe,vxe,tn,Txe,YG,Exe,el=y(()=>{"use strict";F();VG();wxe=[["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]],Sxe=[["::",96],["64:ff9b::",96],["fc00::",7],["fe80::",10]],vxe=(()=>{let e=new hxe;for(let[t,n]of wxe)e.addSubnet(t,n,"ipv4");for(let[t,n]of Sxe)e.addSubnet(t,n,"ipv6");return e})(),tn=class extends Error{constructor(t){super(t),this.name="EgressBlockedError"}};Txe=new bxe({connect:{lookup(e,t,n){QG(e).then(r=>{let o=r.find(s=>QP(s.address));if(o!==void 0){n(new tn(`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,ZP(i.address))},r=>n(r,"",0))}}});YG=20,Exe=new Set([301,302,303,307,308])});var tI={};lt(tI,{enforceDomainPolicy:()=>Nr,loadBrowserConfig:()=>eI});import{readFileSync as xxe}from"node:fs";import{join as Rxe}from"path";function Axe(e){let n=e.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function ZG(e,t){return Axe(t).test(e)}function Pxe(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(Cxe.has(t))return!0;if(_xe.has(t))return!1}return!1}function e2(e){return e===void 0||e.trim()===""?[]:e.split(",").map(t=>t.trim().toLowerCase()).filter(t=>t.length>0)}function Ixe(e){if(e===void 0||e==="")return"auto";if(e==="playwright"||e==="agent-browser"||e==="auto")return e;throw new Error(`AFK_BROWSER_BACKEND: must be "playwright", "agent-browser", or "auto", got: ${e}`)}function t2(e){let t=e===void 0||e.trim()===""?"default":e.trim();return Hc(t),t}function Mxe(e){if(e===void 0)return!1;let t=e.trim().toLowerCase();return t==="1"||t==="true"||t==="yes"}function Oxe(e){try{return xxe(e,"utf8")}catch(t){if(t.code==="ENOENT")return;throw t}}function $xe(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"||t.backend==="agent-browser"||t.backend==="auto")n.backend=t.backend;else if(t.backend!==void 0)throw new Error(`AFK_BROWSER_BACKEND: must be "playwright", "agent-browser", or "auto", got: ${String(t.backend)}`);return typeof t.defaultProfile=="string"&&(n.defaultProfile=t2(t.defaultProfile)),n}function eI(e){let t=e?.env??k,n=e?.readFileSync??Oxe,r=e?.surface??t.AGENT_SURFACE,o=Pxe(t.AFK_BROWSER_HEADLESS,r),i=e2(t.AFK_BROWSER_ALLOWED_DOMAINS),s=e2(t.AFK_BROWSER_BLOCKED_DOMAINS),a=Mxe(t.AFK_BROWSER_DOM_SNAPSHOTS),l=Ixe(t.AFK_BROWSER_BACKEND),c=t2(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():Rxe(vn(),"browser.json"),f=n(p);if(f===void 0)return u;let g;try{g=JSON.parse(f)}catch(b){throw new Error(`Failed to parse browser config at ${p}: ${String(b)}`)}if(typeof g!="object"||g===null||Array.isArray(g))throw new Error(`Browser config at ${p} must be a JSON object`);let h=$xe(u,g);return h.configPath=p,h}function Nr(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(ZG(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return t.allowedDomains.length>0&&!t.allowedDomains.some(o=>ZG(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var Cxe,_xe,ss=y(()=>{"use strict";F();B();Cxe=new Set(["daemon","subagent","telegram","afk"]),_xe=new Set(["repl","interactive","cli"])});import{readFileSync as Dxe}from"node:fs";import{join as Lxe}from"node:path";import{homedir as Fxe}from"node:os";function Bxe(e){let t=e??Nxe,n;try{n=Dxe(t,"utf8")}catch{return null}let r;try{r=JSON.parse(n)}catch{return null}if(typeof r!="object"||r===null||Array.isArray(r))return null;let o=r;if(typeof o.url!="string"||typeof o.token!="string"||typeof o.pid!="number")return null;let i;try{i=new URL(o.url)}catch{return null}let{hostname:s,protocol:a}=i;if(!(s==="127.0.0.1"||s==="localhost"||s==="::1")||a!=="http:")throw new Error(`Agent Browser connection file contains an untrusted URL: ${o.url}. Only http://127.0.0.1 or http://localhost is permitted.`);return{url:o.url,token:o.token,pid:o.pid,version:typeof o.version=="string"?o.version:"unknown"}}function Uxe(e){try{return process.kill(e,0),!0}catch{return!1}}async function jxe(e,t,n=2e3){try{let r=new AbortController,o=setTimeout(()=>r.abort(),n),i=await fetch(`${e}/health`,{method:"GET",headers:{Authorization:`Bearer ${t}`,Host:"127.0.0.1:8833"},signal:r.signal});return clearTimeout(o),i.ok}catch{return!1}}async function nI(e){let t=Bxe(e);return t===null?{available:!1,connection:null,reason:"connection file missing or invalid"}:Uxe(t.pid)?await jxe(t.url,t.token)?{available:!0,connection:t,reason:null}:{available:!1,connection:t,reason:`health probe failed at ${t.url}`}:{available:!1,connection:t,reason:`stale connection file: PID ${t.pid} not alive`}}var Nxe,n2=y(()=>{"use strict";Nxe=Lxe(Fxe(),".config","agent-browser","connection.json")});async function r2(e){let{config:t,surface:n}=e;if(t.backend==="playwright")return{backend:"playwright",reason:"explicit config: backend=playwright",probeMs:0,availability:null};if(t.backend==="agent-browser"){let s=Date.now(),a=await nI(),l=Date.now()-s;if(!a.available)throw new Error(`AFK_BROWSER_BACKEND=agent-browser but Agent Browser is not available: ${a.reason}`);return{backend:"agent-browser",reason:"explicit config: backend=agent-browser",probeMs:l,availability:a}}if(n&&Hxe.has(n))return{backend:"playwright",reason:`auto: surface "${n}" excluded from Agent Browser`,probeMs:0,availability:null};if(t.headless)return{backend:"playwright",reason:"auto: headless mode requires Playwright",probeMs:0,availability:null};let r=Date.now(),o=await nI(),i=Date.now()-r;return o.available?{backend:"agent-browser",reason:"auto: Agent Browser available and preferred",probeMs:i,availability:o}:{backend:"playwright",reason:`auto: Agent Browser unavailable (${o.reason})`,probeMs:i,availability:o}}var Hxe,o2=y(()=>{"use strict";n2();Hxe=new Set(["daemon","subagent"])});import{createHash as Wxe}from"crypto";function i2(e){return!!(e.role==="textbox"&&e.kind==="password"||e.label&&Kxe.test(e.label))}function s2(e){return Wxe("sha256").update(e,"utf8").digest("hex").slice(0,8)}function a2(e){let t=e.replace(/\s+/g," ").trim();return t.length<=80?t:t.slice(0,77)+"..."}var Kxe,cS=y(()=>{"use strict";Kxe=/password|secret|token|api[_-]?key|otp|2fa/i});import{randomBytes as Gxe}from"crypto";import{mkdir as qxe,stat as zxe,writeFile as Jxe}from"fs/promises";import{join as rI}from"path";import{gzip as Vxe}from"zlib";import{promisify as Yxe}from"util";function Xxe(e){return rI(Qt(e),"browser")}function Qxe(e){return rI(Xxe(e),"screenshots")}function Zxe(){return new Date().toISOString().replace(/[:.]/g,"-")}function eRe(){return Gxe(3).toString("hex")}async function Mu(e,t,n){if(t.length>l2)throw new Error(`writeScreenshotSidecar: buffer exceeds ${l2} byte cap (received ${t.length} bytes). Refusing to write oversized screenshot.`);let r=Qxe(e);await qxe(r,{recursive:!0});let o=`${Zxe()}-${eRe()}-${n}.png`,i=rI(r,o);await Jxe(i,t);let{size:s}=await zxe(i);return{path:i,bytes:s}}var Qut,l2,oI=y(()=>{"use strict";B();cS();Qut=Yxe(Vxe);l2=5*1024*1024});var uS,c2=y(()=>{"use strict";ge();uS=class{baseUrl;token;constructor(t){this.baseUrl=t.url,this.token=t.token}async call(t,n,r=3e4){let o={version:1,method:t,params:n},i=new AbortController,s=setTimeout(()=>i.abort(),r);try{let a=await fetch(`${this.baseUrl}/agent`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.token}`,Host:new URL(this.baseUrl).host},body:JSON.stringify(o),signal:i.signal});if(!a.ok){let c=await a.text().catch(()=>"");throw new Error(`Agent Browser ${t} failed (HTTP ${a.status}): ${c}`)}let l=await a.json();if(l.ok===!1){let c=l.error,u=c?.code??"UNKNOWN",d=c?.message??JSON.stringify(l);throw new Error(`Agent Browser ${t} failed: [${String(u)}] ${String(d)}`)}return l.result}finally{clearTimeout(s)}}async listTabs(){return this.call("tabs.list",null)}async openTab(t){return{tabId:(await this.call("tabs.open",{url:t},6e4)).id}}async closeTab(t){await this.call("page.eval",{id:t,script:"window.close()"}).catch(n=>{U("[browser/agent-browser] closeTab window.close() failed (tab leak expected)",{tabId:t,err:n})})}async read(t,n){return this.call("page.read",{id:t,mode:n?.mode??"main",...n?.query?{query:n.query}:{},...n?.budget?{budget:n.budget}:{}})}async inspect(t,n){return this.call("page.inspect",{id:t,mode:n?.mode??"interactive",...n?.query?{query:n.query}:{},...n?.limit?{limit:n.limit}:{}})}async click(t,n){await this.call("page.click",{id:t,elementId:n})}async fill(t,n,r){await this.call("page.fill",{id:t,elementId:n,value:r})}async press(t,n,r){await this.call("page.press",{id:t,key:n,...r?{elementId:r}:{}})}async select(t,n,r){await this.call("page.select",{id:t,elementId:n,value:r})}async waitFor(t,n,r){await this.call("page.wait",{id:t,condition:n,...r?.value?{value:r.value}:{},...r?.timeout?{timeout:r.timeout}:{}},(r?.timeout??3e4)+5e3)}async evalScript(t,n){return this.call("page.eval",{id:t,script:n})}async screenshot(t){return this.call("page.screenshot",{id:t})}}});function iI(e){return{id:e.id,role:e.role,label:e.label,kind:e.kind,value:e.value,state:{disabled:e.disabled,...e.checked!==void 0?{checked:e.checked}:{},...e.selected!==void 0?{selected:e.selected}:{},...e.expanded!==void 0?{expanded:e.expanded}:{}},bbox:e.bbox,...e.selector?{selector:e.selector}:{}}}function u2(e,t){switch(t.kind){case"element_id":if(e.has(t.elementId))return t.elementId;throw new Error(`Element ${t.elementId} not found in current observation. Call browser_observe to refresh.`);case"selector":return null;case"semantic":return null}}async function sI(e,t,n,r,o,i){switch(n){case"click":await e.click(t,r);break;case"fill":if(o===void 0)throw new Error("fill requires a value");await e.fill(t,r,o);break;case"press":if(o===void 0)throw new Error("press requires a value (key combo)");await e.press(t,o,r);break;case"select":if(o===void 0)throw new Error("select requires a value");await e.select(t,r,o);break;case"hover":throw new Error("hover is not supported by Agent Browser; use element_id from a prior observation to target clicks instead");case"scroll_to":{let s=r.replace(/\\/g,"\\\\").replace(/"/g,'\\"');await e.evalScript(t,`document.querySelector('[data-element-id="${s}"]')?.scrollIntoView({behavior:'smooth',block:'center'})`);break}case"wait_for":await e.waitFor(t,"element",{value:r,timeout:i??1e4});break;default:throw new Error(`Unknown action: ${n}`)}}async function d2(e,t){if(t.target.kind!=="semantic")throw new Error("resolveSemanticAndAct called with non-semantic target");let{elements:n}=await e.client.inspect(e.tabId,{mode:"interactive",query:t.target.text,limit:10}),r=n;if(t.target.role){let l=t.target.role.toLowerCase();r=n.filter(c=>c.role.toLowerCase()===l)}if(r.length===0)throw new Error(`No element found matching semantic target: text="${t.target.text}"`+(t.target.role?`, role="${t.target.role}"`:""));if(r.length>1)return{outcome:"ambiguous_target",query:{text:t.target.text,...t.target.role?{role:t.target.role}:{}},candidates:r.slice(0,5).map(iI)};let i=r[0].id;await sI(e.client,e.tabId,t.action,i,t.value,t.timeoutMs);let s=await e.client.read(e.tabId,{mode:"main"}),a=Nr(s.url,e.config);return a.allowed?{elementId:i}:{outcome:"blocked_by_policy",url:s.url,reason:`action navigated to blocked domain: ${a.reason}`}}var p2=y(()=>{"use strict";ss()});var m2={};lt(m2,{AgentBrowserProvider:()=>aI});var aI,f2=y(()=>{"use strict";ss();oI();c2();p2();aI=class{name="agent-browser";config;client;sessions=new Map;constructor(t,n){this.config=t,this.client=new uS(n)}async open(t){let n=Nr(t.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:t.url,reason:n.reason};let r=this.sessions.get(t.sessionId);if(r)await this.client.evalScript(r.tabId,`window.location.href = ${JSON.stringify(t.url)}`),await this.client.waitFor(r.tabId,"load",{timeout:t.timeoutMs??3e4});else{let{tabId:s}=await this.client.openTab(t.url);await this.client.waitFor(s,"load",{timeout:t.timeoutMs??3e4}),r={tabId:s,observationCounter:0,knownElements:new Map,lastAction:null,lastActionAt:null,currentUrl:null,currentTitle:null},this.sessions.set(t.sessionId,r)}let o=await this.client.read(r.tabId,{mode:"main"}),i=Nr(o.url,this.config);return i.allowed?this.buildObservation(r,t.sessionId,t.screenshot,void 0,"browser_open"):(await this.client.evalScript(r.tabId,"window.location.href = 'about:blank'").catch(()=>{}),{outcome:"blocked_by_policy",url:o.url,reason:`redirected to blocked domain: ${i.reason}`})}async observe(t){let n=this.sessions.get(t.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${t.sessionId}. Call browser_open first.`);return this.buildObservation(n,t.sessionId,t.screenshot,t.maxElements,"browser_observe")}async act(t){let n=this.sessions.get(t.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${t.sessionId}. Call browser_open first.`);let r=u2(n.knownElements,t.target);if(r===null){if(t.target.kind==="semantic"){let s=await d2({client:this.client,config:this.config,tabId:n.tabId},t);return"outcome"in s?s:(n.lastAction=`browser_act:${t.action}`,n.lastActionAt=new Date().toISOString(),this.buildObservation(n,t.sessionId,t.screenshot,void 0,"browser_act"))}throw t.target.kind==="selector"?new Error("selector targets are not supported by Agent Browser; use element_id or semantic targets"):new Error(`Cannot resolve target: ${JSON.stringify(t.target)}`)}await sI(this.client,n.tabId,t.action,r,t.value,t.timeoutMs),n.lastAction=`browser_act:${t.action}`,n.lastActionAt=new Date().toISOString();let o=await this.client.read(n.tabId,{mode:"main"}),i=Nr(o.url,this.config);return i.allowed?this.buildObservation(n,t.sessionId,t.screenshot,void 0,"browser_act"):(await this.client.evalScript(n.tabId,"window.location.href = 'about:blank'").catch(()=>{}),{outcome:"blocked_by_policy",url:o.url,reason:`action navigated to blocked domain: ${i.reason}`})}async render(t){throw new Error("AgentBrowserProvider does not support render(). Use PlaywrightProvider for one-shot content fetches.")}async screenshot(t){let n=this.sessions.get(t.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${t.sessionId}. Call browser_open first.`);if(t.target!==void 0||t.fullPage)throw new Error("Agent Browser does not support element or full-page screenshots; omit target and fullPage.");let r=await this.client.screenshot(n.tabId),o=Buffer.from(r.data,"base64"),i=o.length>=24?o.readUInt32BE(16):0,s=o.length>=24?o.readUInt32BE(20):0;return{path:(await Mu(t.sessionId,o,"browser_screenshot")).path,bytes:o.length,width:i,height:s,dataBase64:r.data,mediaType:"image/png"}}async extract(t){throw new Error("AgentBrowserProvider does not support extract() yet.")}async close(t){let n=this.sessions.get(t.sessionId);if(n){try{await this.client.closeTab(n.tabId)}catch{}this.sessions.delete(t.sessionId)}}describe(t){let n=this.sessions.get(t);return n?{active:!0,url:n.currentUrl,title:n.currentTitle,lastAction:n.lastAction,lastActionAt:n.lastActionAt,openTabs:1}:null}async shutdown(){let t=Array.from(this.sessions.entries()).map(async([,n])=>{try{await this.client.closeTab(n.tabId)}catch{}});await Promise.all(t),this.sessions.clear()}async buildObservation(t,n,r,o,i="browser_open"){let[s,a]=await Promise.all([this.client.read(t.tabId,{mode:"main",budget:4e3}),this.client.inspect(t.tabId,{mode:"interactive",limit:o??80})]),l=a.elements.map(iI),c=o??80,u=l.slice(0,c);t.observationCounter+=1,t.knownElements=new Map(u.map(h=>[h.id,h])),t.currentUrl=s.url,t.currentTitle=s.title;let d=[];l.length>c&&d.push(`page has ${l.length} interactive elements; showing first ${c}`);let p=null;if(r)try{let h=await this.client.screenshot(t.tabId),b=Buffer.from(h.data,"base64");p=(await Mu(n,b,i)).path}catch{d.push("screenshot capture failed")}let f=`obs_${t.observationCounter.toString(36)}`,g={httpStatus:null,loadingState:"idle",hasDialog:!1,consoleErrors:0};return{observationId:f,url:s.url,title:s.title,textSummary:s.content.slice(0,4e3),interactive:u,status:g,warnings:d,screenshotPath:p,capturedAt:new Date().toISOString()}}}});import{existsSync as tRe,readFileSync as nRe}from"node:fs";import{createRequire as rRe}from"node:module";import{dirname as oRe,join as iRe}from"node:path";function y2(e){if(typeof e=="string")return e;let t=[],n=e;for(let r=0;r<aRe&&n instanceof Error;r++)t.push(n.message),n=n.cause;return t.length>0?t.join(" | "):String(e)}function An(e){let t=y2(e);return h2.some(n=>t.includes(n))}function lRe(){try{let t=rRe(import.meta.url).resolve("playwright/package.json"),n=JSON.parse(nRe(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=iRe(oRe(t),o);return tRe(i)?`node ${/\s/.test(i)?`"${i}"`:i} install chromium`:void 0}catch{return}}function Hf(){return g2??=lRe()??sRe,g2}function lI(e){return e.includes("install chromium")}function lr(e,t){let n=y2(e),r=t?.latched===!0?` ${cRe}`:"";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: ${Hf()}.${o}${r}`}return`browser tools require the optional \`playwright\` peer dependency. Install via: pnpm add playwright (then ${Hf()}). Or pick a different tool.${r}`}function Ou(e,t,n=!1){if(!An(e))return e;let r=e instanceof Error?e.message:String(e);return new Error(`${r}
438
438
 
439
- ${lr(e,{headless:t,latched:n})}`,{cause:e})}var h2,sRe,aRe,g2,cRe,dS=y(()=>{"use strict";h2=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],sRe="pnpm exec playwright install chromium",aRe=4;cRe="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 tl from"node:fs";import pS from"node:path";import{randomBytes as uRe}from"node:crypto";function dRe(){try{return"5.211.0"}catch{}try{let e=pS.resolve(import.meta.dirname,"../../../package.json"),t=tl.readFileSync(e,"utf8"),n=JSON.parse(t);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var pRe,mS,b2=y(()=>{"use strict";dS();B();ge();pRe=dRe(),mS=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=(async()=>{let t;try{({chromium:t}=await import("playwright"))}catch(n){let r=Ou(n,this.config.headless,!0);throw this.latchLaunchFailure(r),this.launchPromise=void 0,r}try{let n=await t.launch({headless:this.config.headless});return this.browser=n,this.clearLaunchFailure(),n}catch(n){let r=Ou(n,this.config.headless,!0);throw this.latchLaunchFailure(r),r}finally{this.launchPromise=void 0}})(),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/${pRe}`}}loadStorageState(t){let n=Wc(t);try{if(!tl.existsSync(n))return;let r=JSON.parse(tl.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=Wc(t);if(!tl.existsSync(r))return;let o=await n.storageState(),i=pS.join(pS.dirname(r),`.${pS.basename(r)}.${process.pid}.${uRe(4).toString("hex")}.tmp`);tl.writeFileSync(i,JSON.stringify(o),{mode:384}),tl.chmodSync(i,384),tl.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 mRe}from"node:crypto";function fRe(e){return e?e.replace(/\s+/g," ").trim().slice(0,200):""}function gRe(e,t,n){return`el_${mRe("sha256").update(`${e}:${t}:${n}`).digest("hex").slice(0,6)}`}function hRe(e){let t=e.replace(/\s+/g," ").trim(),n=4e3;return t.length<=n?t:t.slice(0,n)+"\u2026[truncated]"}function w2(e){return e.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function v2(e,t){let n=e.role??"",r=e.name??"";S2.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&t.push(e);for(let i of e.children??[])v2(i,t)}async function yRe(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},k2).catch(()=>[])}async function bRe(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},k2).catch(()=>[])}function wRe(e){let n=e.accessibility;return n!==null&&typeof n=="object"?n:null}async function fS(e,t){let n=t.maxElements??80,r=t.includeHidden??!1,o=[],i=wRe(e),s=i?i.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=yRe(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]),b,w=!1;d!==null?(b=[],v2(d,b)):(o.push("observation skipped accessibility tree (returned null)"),w=!0,b=(await bRe(e)).filter(M=>S2.has(M.role??"")));let S=new Map;for(let _ of p){let M=w2(_.name),N=S.get(M);(!N||N.bbox.w===0&&_.bbox.w>0)&&S.set(M,_)}let v=b.map(_=>({ax:_,dom:S.get(w2(_.name??""))})),E=r?v:v.filter(_=>_.dom?_.dom.bbox.w>0||_.dom.bbox.h>0:!0);E.sort((_,M)=>{let N=_.dom?.bbox.y??0,O=M.dom?.bbox.y??0;if(N!==O)return N-O;let j=_.dom?.bbox.x??0,q=M.dom?.bbox.x??0;return j-q}),E.length>200&&o.push("page has 200+ interactive elements; consider scoping");let x=E.slice(0,n).map((_,M)=>{let N=_.ax.role??"generic",O=_.ax.name??"",j=gRe(N,O,M),q=_.dom?.bbox??{x:0,y:0,w:0,h:0},H=_.dom?.type??null,W=null;_.ax.value!==void 0&&_.ax.value!==null&&(W=String(_.ax.value)),_.ax.checked!==void 0&&(W=String(_.ax.checked)),i2({role:N,kind:H})&&(W="[redacted]");let X={disabled:_.ax.disabled??!1};_.ax.checked!==void 0&&(X.checked=_.ax.checked===!0||_.ax.checked==="mixed"),_.ax.selected!==void 0&&(X.selected=_.ax.selected),_.ax.expanded!==void 0&&(X.expanded=_.ax.expanded);let D;_.dom?.testId?D=`[data-testid="${_.dom.testId}"]`:_.dom?.id&&(D=`#${_.dom.id}`);let G={id:j,role:N,label:fRe(O),kind:H,value:W,state:X,bbox:q};return D!==void 0&&(G.selector=D),G}),C="idle";try{let _=await e.evaluate(()=>document.readyState);_==="loading"?C="loading":_==="interactive"?C="navigating":C="idle"}catch{C="navigating"}C!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),w&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let I=hRe(f),A=`obs_${t.observationCounter.toString(36)}`,P=new Date().toISOString();return{observationId:A,url:g,title:h,textSummary:I,interactive:x,status:{httpStatus:t.httpStatus??null,loadingState:C,hasDialog:t.hasDialog??!1,consoleErrors:t.consoleErrors??0},warnings:o,screenshotPath:t.screenshotPath??null,capturedAt:P}}var S2,k2,T2=y(()=>{"use strict";cS();S2=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);k2="a[href], button, input, select, textarea, [role], [tabindex], label"});async function E2(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 cI(e,t){let n=Math.min(t,5);return(await Promise.all(Array.from({length:n},(o,i)=>E2(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 uI(e,t,n){switch(t.kind){case"element_id":return vRe(e,t,n);case"selector":return kRe(e,t);case"semantic":return TRe(e,t)}}async function vRe(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 cI(o,i);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:s}}async function kRe(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 cI(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${t.selector}]`},candidates:o}}async function TRe(e,t){return t.role!==void 0?ERe(e,t.text,t.role):xRe(e,t.text,t)}async function ERe(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 cI(r,o);return{outcome:"ambiguous_target",query:{text:t,role:n},candidates:i}}async function xRe(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 b=p[h];if(b===void 0)continue;let w=await E2(b.locator,b.index);if(w!==null){let S=`${w.role}:${w.label}:${h}`,v=0;for(let E=0;E<S.length;E++)v=v*31+S.charCodeAt(E)>>>0;f.push({...w,id:`el_${v.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:t},candidates:f}}var x2=y(()=>{"use strict"});async function dI(e,t,n,r){let o=e.url();if(o===n)return null;let i=Nr(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 R2=y(()=>{"use strict";ss()});var mI={};lt(mI,{PlaywrightProvider:()=>pI});function A2(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 pI,fI=y(()=>{"use strict";b2();T2();x2();ss();R2();oI();pI=class{name="playwright";config;launcher;sessions=new Map;constructor(t){this.config=t,this.launcher=new mS(t)}async open(t){let n=Nr(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 dI(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 fS(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 fS(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 uI(r,t.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${A2(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(b){c=b}else c=h}let d=await dI(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 fS(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 uI(r,t.target,o.knownElements);if(u.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${A2(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 Mu(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 Mu(n,o,r);return i}catch{return null}}}});var rl={};lt(rl,{__resetBrowserRegistryForTests:()=>IRe,browserProviderActive:()=>CRe,closeBrowserProvider:()=>hI,getBrowserProvider:()=>ARe,getLastRoutingDecision:()=>PRe,peekBrowserProvider:()=>_Re});function C2(){Promise.resolve(hI()).then(()=>{process.exit(130)})}function _2(){Promise.resolve(hI()).then(()=>{process.exit(143)})}function P2(){Ao=null}function RRe(){gS||(process.on("SIGINT",C2),process.on("SIGTERM",_2),process.on("exit",P2),gS=!0)}function I2(){gS&&(process.removeListener("SIGINT",C2),process.removeListener("SIGTERM",_2),process.removeListener("exit",P2),gS=!1)}async function ARe(e){return Ao!==null?Ao:(nl!==null||(nl=(async()=>{let t=eI(e),n=e?.surface??(e?.env??{}).AGENT_SURFACE??k.AGENT_SURFACE,r=await r2({config:t,surface:n});gI=r;let o;if(r.backend==="agent-browser"){let{AgentBrowserProvider:i}=await Promise.resolve().then(()=>(f2(),m2)),s=r.availability.connection;o=new i(t,s)}else{let{PlaywrightProvider:i}=await Promise.resolve().then(()=>(fI(),mI));o=new i(t)}return RRe(),Ao=o,nl=null,o})()),nl)}async function hI(){if(Ao===null)return;let e=Ao;Ao=null,nl=null,I2(),await e.shutdown()}function CRe(){return Ao!==null}function _Re(){return Ao}function PRe(){return gI}function IRe(){Ao=null,nl=null,gI=null,I2()}var Ao,nl,gS,gI,ol=y(()=>{"use strict";ss();o2();F();Ao=null,nl=null,gS=!1,gI=null});async function M2(e,t){try{return await KG(e,t)}catch(n){return U("[web/scrape] extraction failed",{url:t,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function FRe(e,t){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(ol(),rl)),r=await n();try{return await r.render({url:e,timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:t.requestGuard})}catch(o){if(r.name==="agent-browser"){let{PlaywrightProvider:i}=await Promise.resolve().then(()=>(fI(),mI)),{loadBrowserConfig:s}=await Promise.resolve().then(()=>(ss(),tI)),a=s(),l=new i(a);try{return await l.render({url:e,timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:t.requestGuard})}finally{await l.shutdown()}}throw o}}async function O2(e,t){let n=t.fetchFn??globalThis.fetch,r=t.renderFn??FRe,o=t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{},i=null,s="",a=e,l=null,c=null;try{let d=await is(n,e,{headers:LRe,signal:t.signal},o);l=d.status,a=d.url||e;let p=d.headers.get("content-type")??"";if(d.ok){if(DRe.test(p))throw new Error(`web_scrape markdown mode received binary content (${p.split(";")[0]}). Use mode: "raw" to fetch the bytes, or a different tool.`);let f=await d.text();if($Re.test(p)&&!ORe.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(s=f,i=await M2(f,a),t.signal.aborted)throw t.signal.reason??new Error("aborted")}}catch(d){if(t.signal.aborted||d instanceof tn||d instanceof Error&&d.message.startsWith("web_scrape markdown mode received binary"))throw d;c=d}if(!(i===null||i.textLength<200)&&i!==null){let d=YP({html:s,extractedTextLength:i.textLength});return{title:i.title,markdown:i.markdown,finalUrl:a,usedRender:!1,...d!==void 0?{advisory:d}:{}}}try{await jf(e,o);let d=await r(e,{timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:f=>jf(f,o)});d.finalUrl!==e&&/^https?:\/\//i.test(d.finalUrl)&&await jf(d.finalUrl,o);let p=await M2(d.html,d.finalUrl);if(t.signal.aborted)throw t.signal.reason??new Error("aborted");if(i===null||p.textLength>=i.textLength){let f=YP({html:d.html,extractedTextLength:p.textLength});return{title:p.title,markdown:p.markdown,finalUrl:d.finalUrl,usedRender:!0,...f!==void 0?{advisory:f}:{}}}}catch(d){if(t.signal.aborted||d instanceof tn)throw d;if(i===null){let p=d instanceof Error?d.message:String(d),f=c instanceof Error?c.message:`HTTP ${l??"error"}`,g=new Error(`web_scrape could not retrieve ${e}: fetch failed (${f}) and render failed (${p}).`);throw g.cause=d,g}}if(i!==null)return{title:i.title,markdown:i.markdown,finalUrl:a,usedRender:!1};throw new Error(`web_scrape could not retrieve any content from ${e} (HTTP ${l??"error"}).`)}var ORe,$Re,DRe,LRe,$2=y(()=>{"use strict";GG();XP();el();ge();ORe=/(text\/html|application\/xhtml\+xml)/i,$Re=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,DRe=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,LRe={"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 URe(e){let t=e.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let i=await t(NRe,{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),BRe),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!i.ok){let l="";try{let u=await i.text(),d=se(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 D2(e){return e.exaApiKey!==void 0&&e.exaApiKey.trim()!==""?URe({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 L2(e,t){if(t.length===0)return`# Search results for "${e}"
439
+ ${lr(e,{headless:t,latched:n})}`,{cause:e})}var h2,sRe,aRe,g2,cRe,dS=y(()=>{"use strict";h2=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],sRe="pnpm exec playwright install chromium",aRe=4;cRe="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 tl from"node:fs";import pS from"node:path";import{randomBytes as uRe}from"node:crypto";function dRe(){try{return"5.212.1"}catch{}try{let e=pS.resolve(import.meta.dirname,"../../../package.json"),t=tl.readFileSync(e,"utf8"),n=JSON.parse(t);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var pRe,mS,b2=y(()=>{"use strict";dS();B();ge();pRe=dRe(),mS=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=(async()=>{let t;try{({chromium:t}=await import("playwright"))}catch(n){let r=Ou(n,this.config.headless,!0);throw this.latchLaunchFailure(r),this.launchPromise=void 0,r}try{let n=await t.launch({headless:this.config.headless});return this.browser=n,this.clearLaunchFailure(),n}catch(n){let r=Ou(n,this.config.headless,!0);throw this.latchLaunchFailure(r),r}finally{this.launchPromise=void 0}})(),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/${pRe}`}}loadStorageState(t){let n=Wc(t);try{if(!tl.existsSync(n))return;let r=JSON.parse(tl.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=Wc(t);if(!tl.existsSync(r))return;let o=await n.storageState(),i=pS.join(pS.dirname(r),`.${pS.basename(r)}.${process.pid}.${uRe(4).toString("hex")}.tmp`);tl.writeFileSync(i,JSON.stringify(o),{mode:384}),tl.chmodSync(i,384),tl.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 mRe}from"node:crypto";function fRe(e){return e?e.replace(/\s+/g," ").trim().slice(0,200):""}function gRe(e,t,n){return`el_${mRe("sha256").update(`${e}:${t}:${n}`).digest("hex").slice(0,6)}`}function hRe(e){let t=e.replace(/\s+/g," ").trim(),n=4e3;return t.length<=n?t:t.slice(0,n)+"\u2026[truncated]"}function w2(e){return e.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function v2(e,t){let n=e.role??"",r=e.name??"";S2.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&t.push(e);for(let i of e.children??[])v2(i,t)}async function yRe(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},k2).catch(()=>[])}async function bRe(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},k2).catch(()=>[])}function wRe(e){let n=e.accessibility;return n!==null&&typeof n=="object"?n:null}async function fS(e,t){let n=t.maxElements??80,r=t.includeHidden??!1,o=[],i=wRe(e),s=i?i.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=yRe(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]),b,w=!1;d!==null?(b=[],v2(d,b)):(o.push("observation skipped accessibility tree (returned null)"),w=!0,b=(await bRe(e)).filter(M=>S2.has(M.role??"")));let S=new Map;for(let _ of p){let M=w2(_.name),N=S.get(M);(!N||N.bbox.w===0&&_.bbox.w>0)&&S.set(M,_)}let v=b.map(_=>({ax:_,dom:S.get(w2(_.name??""))})),E=r?v:v.filter(_=>_.dom?_.dom.bbox.w>0||_.dom.bbox.h>0:!0);E.sort((_,M)=>{let N=_.dom?.bbox.y??0,O=M.dom?.bbox.y??0;if(N!==O)return N-O;let j=_.dom?.bbox.x??0,q=M.dom?.bbox.x??0;return j-q}),E.length>200&&o.push("page has 200+ interactive elements; consider scoping");let x=E.slice(0,n).map((_,M)=>{let N=_.ax.role??"generic",O=_.ax.name??"",j=gRe(N,O,M),q=_.dom?.bbox??{x:0,y:0,w:0,h:0},H=_.dom?.type??null,W=null;_.ax.value!==void 0&&_.ax.value!==null&&(W=String(_.ax.value)),_.ax.checked!==void 0&&(W=String(_.ax.checked)),i2({role:N,kind:H})&&(W="[redacted]");let X={disabled:_.ax.disabled??!1};_.ax.checked!==void 0&&(X.checked=_.ax.checked===!0||_.ax.checked==="mixed"),_.ax.selected!==void 0&&(X.selected=_.ax.selected),_.ax.expanded!==void 0&&(X.expanded=_.ax.expanded);let D;_.dom?.testId?D=`[data-testid="${_.dom.testId}"]`:_.dom?.id&&(D=`#${_.dom.id}`);let G={id:j,role:N,label:fRe(O),kind:H,value:W,state:X,bbox:q};return D!==void 0&&(G.selector=D),G}),C="idle";try{let _=await e.evaluate(()=>document.readyState);_==="loading"?C="loading":_==="interactive"?C="navigating":C="idle"}catch{C="navigating"}C!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),w&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let I=hRe(f),A=`obs_${t.observationCounter.toString(36)}`,P=new Date().toISOString();return{observationId:A,url:g,title:h,textSummary:I,interactive:x,status:{httpStatus:t.httpStatus??null,loadingState:C,hasDialog:t.hasDialog??!1,consoleErrors:t.consoleErrors??0},warnings:o,screenshotPath:t.screenshotPath??null,capturedAt:P}}var S2,k2,T2=y(()=>{"use strict";cS();S2=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);k2="a[href], button, input, select, textarea, [role], [tabindex], label"});async function E2(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 cI(e,t){let n=Math.min(t,5);return(await Promise.all(Array.from({length:n},(o,i)=>E2(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 uI(e,t,n){switch(t.kind){case"element_id":return vRe(e,t,n);case"selector":return kRe(e,t);case"semantic":return TRe(e,t)}}async function vRe(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 cI(o,i);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:s}}async function kRe(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 cI(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${t.selector}]`},candidates:o}}async function TRe(e,t){return t.role!==void 0?ERe(e,t.text,t.role):xRe(e,t.text,t)}async function ERe(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 cI(r,o);return{outcome:"ambiguous_target",query:{text:t,role:n},candidates:i}}async function xRe(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 b=p[h];if(b===void 0)continue;let w=await E2(b.locator,b.index);if(w!==null){let S=`${w.role}:${w.label}:${h}`,v=0;for(let E=0;E<S.length;E++)v=v*31+S.charCodeAt(E)>>>0;f.push({...w,id:`el_${v.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:t},candidates:f}}var x2=y(()=>{"use strict"});async function dI(e,t,n,r){let o=e.url();if(o===n)return null;let i=Nr(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 R2=y(()=>{"use strict";ss()});var mI={};lt(mI,{PlaywrightProvider:()=>pI});function A2(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 pI,fI=y(()=>{"use strict";b2();T2();x2();ss();R2();oI();pI=class{name="playwright";config;launcher;sessions=new Map;constructor(t){this.config=t,this.launcher=new mS(t)}async open(t){let n=Nr(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 dI(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 fS(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 fS(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 uI(r,t.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${A2(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(b){c=b}else c=h}let d=await dI(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 fS(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 uI(r,t.target,o.knownElements);if(u.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${A2(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 Mu(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 Mu(n,o,r);return i}catch{return null}}}});var rl={};lt(rl,{__resetBrowserRegistryForTests:()=>IRe,browserProviderActive:()=>CRe,closeBrowserProvider:()=>hI,getBrowserProvider:()=>ARe,getLastRoutingDecision:()=>PRe,peekBrowserProvider:()=>_Re});function C2(){Promise.resolve(hI()).then(()=>{process.exit(130)})}function _2(){Promise.resolve(hI()).then(()=>{process.exit(143)})}function P2(){Ao=null}function RRe(){gS||(process.on("SIGINT",C2),process.on("SIGTERM",_2),process.on("exit",P2),gS=!0)}function I2(){gS&&(process.removeListener("SIGINT",C2),process.removeListener("SIGTERM",_2),process.removeListener("exit",P2),gS=!1)}async function ARe(e){return Ao!==null?Ao:(nl!==null||(nl=(async()=>{let t=eI(e),n=e?.surface??(e?.env??{}).AGENT_SURFACE??k.AGENT_SURFACE,r=await r2({config:t,surface:n});gI=r;let o;if(r.backend==="agent-browser"){let{AgentBrowserProvider:i}=await Promise.resolve().then(()=>(f2(),m2)),s=r.availability.connection;o=new i(t,s)}else{let{PlaywrightProvider:i}=await Promise.resolve().then(()=>(fI(),mI));o=new i(t)}return RRe(),Ao=o,nl=null,o})()),nl)}async function hI(){if(Ao===null)return;let e=Ao;Ao=null,nl=null,I2(),await e.shutdown()}function CRe(){return Ao!==null}function _Re(){return Ao}function PRe(){return gI}function IRe(){Ao=null,nl=null,gI=null,I2()}var Ao,nl,gS,gI,ol=y(()=>{"use strict";ss();o2();F();Ao=null,nl=null,gS=!1,gI=null});async function M2(e,t){try{return await KG(e,t)}catch(n){return U("[web/scrape] extraction failed",{url:t,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function FRe(e,t){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(ol(),rl)),r=await n();try{return await r.render({url:e,timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:t.requestGuard})}catch(o){if(r.name==="agent-browser"){let{PlaywrightProvider:i}=await Promise.resolve().then(()=>(fI(),mI)),{loadBrowserConfig:s}=await Promise.resolve().then(()=>(ss(),tI)),a=s(),l=new i(a);try{return await l.render({url:e,timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:t.requestGuard})}finally{await l.shutdown()}}throw o}}async function O2(e,t){let n=t.fetchFn??globalThis.fetch,r=t.renderFn??FRe,o=t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{},i=null,s="",a=e,l=null,c=null;try{let d=await is(n,e,{headers:LRe,signal:t.signal},o);l=d.status,a=d.url||e;let p=d.headers.get("content-type")??"";if(d.ok){if(DRe.test(p))throw new Error(`web_scrape markdown mode received binary content (${p.split(";")[0]}). Use mode: "raw" to fetch the bytes, or a different tool.`);let f=await d.text();if($Re.test(p)&&!ORe.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(s=f,i=await M2(f,a),t.signal.aborted)throw t.signal.reason??new Error("aborted")}}catch(d){if(t.signal.aborted||d instanceof tn||d instanceof Error&&d.message.startsWith("web_scrape markdown mode received binary"))throw d;c=d}if(!(i===null||i.textLength<200)&&i!==null){let d=YP({html:s,extractedTextLength:i.textLength});return{title:i.title,markdown:i.markdown,finalUrl:a,usedRender:!1,...d!==void 0?{advisory:d}:{}}}try{await jf(e,o);let d=await r(e,{timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:f=>jf(f,o)});d.finalUrl!==e&&/^https?:\/\//i.test(d.finalUrl)&&await jf(d.finalUrl,o);let p=await M2(d.html,d.finalUrl);if(t.signal.aborted)throw t.signal.reason??new Error("aborted");if(i===null||p.textLength>=i.textLength){let f=YP({html:d.html,extractedTextLength:p.textLength});return{title:p.title,markdown:p.markdown,finalUrl:d.finalUrl,usedRender:!0,...f!==void 0?{advisory:f}:{}}}}catch(d){if(t.signal.aborted||d instanceof tn)throw d;if(i===null){let p=d instanceof Error?d.message:String(d),f=c instanceof Error?c.message:`HTTP ${l??"error"}`,g=new Error(`web_scrape could not retrieve ${e}: fetch failed (${f}) and render failed (${p}).`);throw g.cause=d,g}}if(i!==null)return{title:i.title,markdown:i.markdown,finalUrl:a,usedRender:!1};throw new Error(`web_scrape could not retrieve any content from ${e} (HTTP ${l??"error"}).`)}var ORe,$Re,DRe,LRe,$2=y(()=>{"use strict";GG();XP();el();ge();ORe=/(text\/html|application\/xhtml\+xml)/i,$Re=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,DRe=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,LRe={"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 URe(e){let t=e.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let i=await t(NRe,{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),BRe),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!i.ok){let l="";try{let u=await i.text(),d=se(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 D2(e){return e.exaApiKey!==void 0&&e.exaApiKey.trim()!==""?URe({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 L2(e,t){if(t.length===0)return`# Search results for "${e}"
440
440
 
441
441
  (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(`
442
442
  `).trimEnd()}var NRe,BRe,F2=y(()=>{"use strict";Fe();NRe="https://api.exa.ai/search",BRe=10});function hS(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 il=y(()=>{"use strict";dS()});function qRe(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=jRe;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,HRe)}let a=WRe;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,KRe)}return{mode:r,url:o,query:i,timeoutMs:s,maxBytes:a}}function yI(e,t){return Buffer.byteLength(e,"utf8")<=t?{content:e,truncated:!1}:{content:$r(e,t),truncated:!0}}function zRe(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=qRe(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 Za(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 is(t,s.url,h,r)}catch(h){return a.signal.aborted?{content:`web_scrape aborted: ${u()}`,isError:!0}:h instanceof tn?{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=yI(f,s.maxBytes);return{content:g.content,...g.truncated?{truncated:!0}:{}}}if(s.mode==="markdown")try{let p=await O2(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=yI(qG(p.markdown,p.advisory),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 tn)return{content:`web_scrape blocked: ${p.message}`,isError:!0};let f=p instanceof Error?p.message:String(p),g=An(p)&&!lI(f)?` (the render fallback needs the optional Playwright browser \u2014 run \`${Hf()}\`)`:"";return{content:`web_scrape markdown error: ${f}${g}`,isError:!0}}let d=D2({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:GRe,timeoutMs:s.timeoutMs,signal:a.signal}),f=yI(L2(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 jRe,HRe,WRe,KRe,GRe,N2,B2=y(()=>{"use strict";$2();F2();el();bo();XP();il();jRe=3e4,HRe=12e4,WRe=1e5,KRe=1e6,GRe=10;N2=zRe()});function YRe(e){return JRe.has(e)?"low":e==="DELETE"?"high":"medium"}function XRe(e){return VRe.has(e)}function eAe(e){let t={};return e.forEach((n,r)=>{let o=r.toLowerCase();ZRe.has(o)||QRe.some(i=>o.startsWith(i))||(t[r]=n)}),t}function tAe(e,t){if(e==null)return{serialized:void 0,inferredContentType:void 0};let n=Object.keys(t).some(o=>o.toLowerCase()==="content-type");return typeof e=="string"?{serialized:e,inferredContentType:n?void 0:"text/plain"}:{serialized:JSON.stringify(e),inferredContentType:n?void 0:"application/json"}}function nAe(e,t,n){let r=Buffer.byteLength(e,"utf8"),o=e,i=!1;if(r>n&&(o=$r(e,n),i=!0),!i&&/application\/json/i.test(t))try{return{body:JSON.parse(o),truncated:!1}}catch{}return{body:o,truncated:i}}async function H2(e){let{url:t,method:n,signal:r,domainCheck:o,recordEffect:i}=e,s=Math.min(e.maxResponseBytes??bI,wI),a={...e.headers},l=e.fetchFn??globalThis.fetch,c=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},u=YRe(n);if(o!==void 0){let A=o(t);if(!A.allowed)throw Object.assign(new Error(`web_request blocked by domain policy: ${A.reason}`),{name:"DomainPolicyError"})}let d=await Za(t,c);if(!d.allowed)throw new tn(d.reason);let{serialized:p,inferredContentType:f}=tAe(e.body,a);f!==void 0&&(a["content-type"]=f);let g={method:n,headers:Object.keys(a).length>0?a:void 0,body:p,signal:r},b=XRe(n)?{retries:2,baseDelayMs:300,maxDelayMs:5e3}:{retries:0},w=Date.now(),S;try{S=await is(l,t,g,{...c,retry:b})}catch(A){throw A instanceof tn,A}let v=Date.now()-w,E=S.headers.get("content-type")??"",T;try{let A=S.body?.getReader();if(!A)T="";else{let P=[],_=0,M=s*2;for(;;){let{done:N,value:O}=await A.read();if(N||!O)break;if(P.push(O),_+=O.byteLength,_>=M){await A.cancel();break}}T=new TextDecoder().decode(Buffer.concat(P,_))}}catch{T=""}let{body:x,truncated:C}=nAe(T,E,s),I=eAe(S.headers);return i!==void 0&&Promise.resolve(i({url:t,method:n,status:S.status,risk:u,timing_ms:v})).catch(()=>{}),{status:S.status,headers:I,body:x,truncated:C,timing_ms:v,risk:u}}function W2(e){if(typeof e!="string"||e.trim().length===0)return{error:"method must be a non-empty string (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS)"};let t=e.trim().toUpperCase(),n=["GET","POST","PUT","PATCH","DELETE","HEAD","OPTIONS"];return n.includes(t)?t:{error:`method "${e}" is not supported \u2014 must be one of: ${n.join(", ")}`}}var U2,j2,bI,wI,JRe,VRe,QRe,ZRe,K2=y(()=>{"use strict";el();bo();U2=3e4,j2=12e4,bI=1e5,wI=1e6,JRe=new Set(["GET","HEAD","OPTIONS"]),VRe=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]);QRe=["set-cookie","x-"],ZRe=new Set(["server","via","age","vary","authorization","www-authenticate"])});function rAe(e){if(!e||typeof e!="object")return{error:"Invalid input: expected an object"};let t=e;if(typeof t.url!="string"||t.url.length===0)return{error:'Invalid input: "url" must be a non-empty string'};let n;try{n=new URL(t.url)}catch{return{error:`Invalid input: "${t.url}" is not a valid absolute URL`}}if(n.protocol!=="http:"&&n.protocol!=="https:")return{error:`Invalid input: protocol "${n.protocol}" not supported (http/https only)`};n.username="",n.password="";let r=n.toString(),o=W2(t.method);if(typeof o=="object"&&"error"in o)return{error:`Invalid input: ${o.error}`};let i=o,s;if(t.body!==void 0&&t.body!==null){if(typeof t.body!="string"&&typeof t.body!="object")return{error:'Invalid input: "body" must be a string, object, or array'};s=t.body}let a={};if(t.headers!==void 0){if(typeof t.headers!="object"||t.headers===null||Array.isArray(t.headers))return{error:'Invalid input: "headers" must be a string-keyed object'};let d=t.headers;for(let[p,f]of Object.entries(d)){if(typeof f!="string")return{error:`Invalid input: header value for "${p}" must be a string`};a[p]=f}}let l=U2;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'};l=Math.min(t.timeout_ms,j2)}let c=bI;if(t.max_response_bytes!==void 0){if(typeof t.max_response_bytes!="number"||!Number.isFinite(t.max_response_bytes)||t.max_response_bytes<=0)return{error:'Invalid input: "max_response_bytes" must be a positive finite number'};c=Math.min(t.max_response_bytes,wI)}let u;if(t.credential!==void 0){if(typeof t.credential!="string"||t.credential.length===0)return{error:'Invalid input: "credential" must be a non-empty string (an env var name)'};u=t.credential}return{url:r,method:i,body:s,headers:a,timeoutMs:l,maxResponseBytes:c,credential:u}}function oAe(e={}){let t=e.fetchFn??globalThis.fetch,n=e.env??process.env;async function r(){if(e.domainCheck!==void 0)return e.domainCheck;try{let{loadBrowserConfig:o,enforceDomainPolicy:i}=await Promise.resolve().then(()=>(ss(),tI)),s=o();return a=>i(a,s)}catch{return}}return async(o,i)=>{if(typeof t!="function")return{content:"web_request unavailable: global fetch() is not present (agent-afk requires Node 20+).",isError:!0};let s=rAe(o);if("error"in s)return{content:s.error,isError:!0};if(i.aborted){let p=i.reason;return{content:`web_request aborted: ${p instanceof Error?p.message:String(p??"aborted")}`,isError:!0}}let a={...s.headers};if(s.credential!==void 0){let p=n[s.credential];if(p===void 0||p.trim().length===0)return{content:`web_request credential error: environment variable "${s.credential}" is not set. Set it in afk.env or export it in the shell before starting AFK.`,isError:!0};if(Object.keys(a).some(g=>g.toLowerCase()==="authorization"))return{content:'web_request credential error: both "credential" and an explicit Authorization header were provided. Use one or the other.',isError:!0};a.Authorization=`Bearer ${p}`}let l=new AbortController,c=()=>l.abort(i.reason),u,d=()=>{let p=l.signal.reason;return p instanceof Error?p.message:String(p??"aborted")};try{i.addEventListener("abort",c,{once:!0}),u=setTimeout(()=>{l.abort(new Error(`web_request timeout after ${s.timeoutMs}ms`))},s.timeoutMs);let p=await r(),f={url:s.url,method:s.method,body:s.body,headers:a,maxResponseBytes:s.maxResponseBytes,signal:l.signal,fetchFn:t,lookupFn:e.lookupFn,domainCheck:p,recordEffect:e.recordEffect},g;try{g=await H2(f)}catch(S){if(l.signal.aborted)return{content:`web_request aborted: ${d()}`,isError:!0};if(S instanceof tn)return{content:`web_request blocked: ${S.message}`,isError:!0};let v=S instanceof Error&&S.name==="DomainPolicyError"?"blocked":"network error",E=S instanceof Error?S.message:String(S);return{content:`web_request ${v}: ${E}`,isError:!0}}if(l.signal.aborted)return{content:`web_request aborted: ${d()}`,isError:!0};let h=g.body;if(typeof h=="string")h=mt(h);else if(typeof h=="object"&&h!==null){let S=mt(JSON.stringify(h));try{h=JSON.parse(S)}catch{h=S}}let b={status:g.status,headers:g.headers,body:h,timing_ms:g.timing_ms,...g.truncated?{truncated:!0}:{}};return{content:JSON.stringify(b,null,2),...g.truncated?{truncated:!0}:{}}}finally{u!==void 0&&clearTimeout(u),i.removeEventListener("abort",c)}}}var G2,q2=y(()=>{"use strict";K2();el();Pr();G2=oAe()});import{existsSync as J2,mkdirSync as iAe,readFileSync as sAe,renameSync as aAe,unlinkSync as lAe,writeFileSync as cAe}from"node:fs";import{dirname as z2,join as uAe}from"node:path";import{randomBytes as dAe}from"node:crypto";function Gt(e){let t=e??ub();if(!J2(t))return[];try{let n=sAe(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 Br(e,t){let n=t??ub();iAe(z2(n),{recursive:!0});let r=uAe(z2(n),`.schedules.json.${process.pid}.${dAe(4).toString("hex")}.tmp`),o=JSON.stringify(e,null,2);try{cAe(r,o,"utf-8"),aAe(r,n)}catch(i){try{J2(r)&&lAe(r)}catch{}throw i}}function $u(e,t){let n=Gt(t),r=n.map(l=>l.id),o=pAe(e.name),i=mAe(o,r),s=new Date().toISOString(),a={...e,notifyOn:e.notifyOn??"failure",id:i,createdAt:s,updatedAt:s};return n.push(a),Br(n,t),a}function Du(e,t){let n=Gt(t),r=n.length,o=n.filter(i=>i.id!==e);return o.length===r?!1:(Br(o,t),!0)}function sl(e,t){return Gt(t).find(n=>n.id===e)}function pAe(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"")}function mAe(e,t){if(!t.includes(e))return e;let n=2;for(;t.includes(`${e}-${n}`);)n+=1;return`${e}-${n}`}function as(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 Wf=y(()=>{"use strict";B()});import{existsSync as fAe,readFileSync as gAe}from"node:fs";import{join as hAe}from"node:path";async function ft(e,t,n){let r,o;try{let i=hAe(ka("default"),"port");if(!fAe(i))return{synced:!1,detail:"daemon-not-detected (no port file)"};let s=gAe(i,"utf-8").trim(),a=SI(s);if(!a)return{synced:!1,detail:"daemon-not-detected (invalid port file)"};({host:r,port:o}=a)}catch{return{synced:!1,detail:"daemon-not-detected (unreadable port file)"}}try{let i=r.includes(":")?`[${r}]`:r,s=await fetch(`http://${i}:${o}${t}`,{method:e,headers:{"Content-Type":"application/json"},body:n!==void 0?JSON.stringify(n):void 0,signal:AbortSignal.timeout(2e3)});return s.ok?{synced:!0,detail:"synced"}:e==="POST"&&s.status===409?{synced:!0,detail:"already-registered"}:e==="DELETE"&&s.status===404?{synced:!0,detail:"not-registered"}:{synced:!1,detail:`daemon-rejected (HTTP ${s.status})`}}catch{return{synced:!1,detail:"daemon-unreachable (stale port file or network error)"}}}function SI(e){let t=parseInt(e,10);if(String(t)===e&&!Number.isNaN(t))return t<1||t>65535?null:{host:"localhost",port:t};let n=e.lastIndexOf(":");if(n<1)return null;let r=e.slice(0,n),o=e.slice(n+1);if(!/^\d+$/.test(o))return null;let i=parseInt(o,10);return Number.isNaN(i)||i<1||i>65535||/^:+$/.test(r)?null:{host:r.startsWith("[")&&r.endsWith("]")?r.slice(1,-1):r,port:i}}var Hn,yS=y(()=>{"use strict";B();Hn="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 yAe}from"node:fs";import{readFile as bAe}from"node:fs/promises";var V2,Y2,X2,Q2,Z2=y(()=>{"use strict";Wf();B();yS();V2=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=$u({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 ft("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 ft("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:Hn}})}},Y2=async(e,t)=>{let n=Gt();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})))}},X2=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=Nn();if(!yAe(i))return{content:JSON.stringify([])};let s;try{let c=await bAe(i);s=(c.length>1048576?c.subarray(c.length-1048576):c).toString("utf-8")}catch{return{content:JSON.stringify([])}}let a=s.split(`
@@ -1614,7 +1614,8 @@ Do not drift into open-ended exploration when the objective is concrete.
1614
1614
 
1615
1615
  - Act without asking when intent is clear and the action is reversible.
1616
1616
  - Ask only when the next action depends on missing information, or when proceeding would cross an irreversible, external, or shared-resource boundary.
1617
- - Batch independent actions into one wave; sequence dependent actions.
1617
+ - Parallel by default. When work decomposes into independent sub-tasks, dispatch them in one concurrent wave -- not sequentially. Serial dispatch requires justification: use it only when one task's output is load-bearing input for the next.
1618
+ - The scarce resource is human wall-clock time, not agent compute. Spending parallel machine time to compress human waiting time is the right trade when the operator is away.
1618
1619
  - Delegate bounded sub-tasks; verify their output before relying on it.
1619
1620
  - Stop when further work yields diminishing returns.
1620
1621
 
@@ -1660,7 +1661,7 @@ The transcript is not a user channel. AFK users see bridge messages, files, comm
1660
1661
  survive reboots and are not recorded in agent state.
1661
1662
  - **Tool schemas are authoritative.** Required fields are required. If a value is unknown, fetch it or ask. Do not guess.
1662
1663
  - **Do not skip Observe or Update to save tokens.** Stale-state errors cost more than the tokens saved.
1663
- - **Parallelize independent calls; sequence dependent ones.**
1664
+ - **Parallel by default** (see Delegation). Sequence only what genuinely depends on a prior result.
1664
1665
  - **Re-check shared mutable state after divergence, delay, or failure.**
1665
1666
  - **Do not use emdashes.**
1666
1667
 
@@ -1675,11 +1676,13 @@ Default to delegation for any task that would otherwise:
1675
1676
  - run two or more independent investigations that could happen in parallel,
1676
1677
  - consume more main-session context than the subagent's compressed answer would.
1677
1678
 
1678
- Stay inline for: single-file edits, localized fixes visible in <2 reads, conversational answers, explicit user requests for a direct tool call, and tasks where dispatch overhead exceeds the work.
1679
+ Stay inline for: single-file edits, localized fixes visible in <2 reads, conversational answers, explicit user requests for a direct tool call, tasks where dispatch overhead exceeds the work, and strictly sequential chains where each step genuinely requires the previous step's output as prompt input.
1679
1680
 
1680
1681
  When dispatching a subagent, assume zero prior context. Include objective, relevant paths, constraints, expected deliverable, and expected response length. State what not to do and when to stop. Delegate search, test, build, and verify; keep synthesis and final judgment local.
1681
1682
 
1682
- Parallelize independent subagents in one wave. Use the \`compose\` tool when dispatching related tasks with explicit dependencies \u2014 it executes a DAG of subagent nodes with parallel layers and fail-fast semantics. Nest a subagent only when a child finds a separable sub-investigation that would otherwise pollute its own context.
1683
+ Scheduling posture: parallel is the default, serial is the exception. Before starting multi-step work, decompose it: list sub-tasks, mark genuine dependencies, dispatch all non-dependent work in a single wave. Do not serialize investigation, research, verification, or test-running that could proceed concurrently. The governing metric is wall-clock time to correct completion, not total agent compute. This posture applies to the root coordinator; child subagents should focus on their scoped task rather than recursively fanning out unless their own task independently decomposes.
1684
+
1685
+ Use the \`compose\` tool when dispatching related tasks with explicit dependencies \u2014 it executes a DAG of subagent nodes with parallel layers and fail-fast semantics. When building a DAG, minimize the longest dependency chain \u2014 that chain determines wall-clock completion time. Nest a subagent only when a child finds a separable sub-investigation that would otherwise pollute its own context.
1683
1686
 
1684
1687
  Subagents return compressed findings, not raw exploration. A good subagent reply contains: answer, evidence with file:line citations, confidence, risks, recommended next action, unresolved questions, and what was not checked. Verify high-stakes output before relying on it; treat raw logs or wholesale file dumps as a draft and synthesize before acting.
1685
1688
 
@@ -1782,7 +1785,7 @@ ${r}`}function _n(e=process.cwd()){let t=m7(),n=Ve(void 0,e),r=n.systemPrompt,o=
1782
1785
 
1783
1786
  The instructions below come from this operator's configuration (AFK.md, afk.config.json, or AFK_SYSTEM_PROMPT). Treat them as refinements layered on top of the operating posture above \u2014 follow them unless they conflict with the Priorities or Constraints already stated.`});function Ll(e,t){let n=e?.trim().toLowerCase()??"",r=(k.AFK_PROVIDER??"").trim().toLowerCase(),o=n.length>0||r==="xai"||r==="xai-oauth"||r==="xai_oauth",i=e;if(i===void 0&&t?.model!==void 0){let a=ae(t.model,{...t.openaiBaseUrl!==void 0?{openaiBaseUrl:t.openaiBaseUrl}:{}});a==="openai-compatible"&&(i="openai-compatible"),(a==="xai"||a==="xai-oauth")&&(i=a)}if(i===void 0)return;if(!y7.includes(i))throw new Error(`Invalid --provider value: ${i}. Expected one of: ${y7.join(", ")}`);let s=()=>{let a=[...Tn,...Ga,...$t,...Ba,...cu,Kn];return t?.subagentExecutor&&a.push("agent"),t?.skillExecutor&&a.push("skill"),t?.composeExecutor&&a.push("compose"),t?.mcpManager&&a.push(...t.mcpManager.getMcpToolWireNames()),a};if(i==="anthropic"||i==="anthropic-direct")return new Xe({permissions:{allowedTools:s()},subagentExecutor:t?.subagentExecutor,skillExecutor:t?.skillExecutor,composeExecutor:t?.composeExecutor,...t?.memoryStore!==void 0?{memoryStore:t.memoryStore}:{},...t?.workspaceStore!==void 0?{workspaceStore:t.workspaceStore}:{},...t?.mcpManager!==void 0?{mcpManager:t.mcpManager}:{},...t?.fastModeController!==void 0?{fastModeController:t.fastModeController}:{}});if(i==="openai"||i==="openai-compatible")return new sn({permissions:{allowedTools:s()},...t?.subagentExecutor!==void 0?{subagentExecutor:t.subagentExecutor}:{},...t?.skillExecutor!==void 0?{skillExecutor:t.skillExecutor}:{},...t?.composeExecutor!==void 0?{composeExecutor:t.composeExecutor}:{},...t?.memoryStore!==void 0?{memoryStore:t.memoryStore}:{},...t?.workspaceStore!==void 0?{workspaceStore:t.workspaceStore}:{},...t?.mcpManager!==void 0?{mcpManager:t.mcpManager}:{},...t?.openaiBaseUrl!==void 0?{baseURL:t.openaiBaseUrl}:{}});if(i==="xai"||i==="xai-oauth"){let a=mT(i,o);return new $l({permissions:{allowedTools:s()},...a!==void 0?{authMode:a}:{},...t?.subagentExecutor!==void 0?{subagentExecutor:t.subagentExecutor}:{},...t?.skillExecutor!==void 0?{skillExecutor:t.skillExecutor}:{},...t?.composeExecutor!==void 0?{composeExecutor:t.composeExecutor}:{},...t?.memoryStore!==void 0?{memoryStore:t.memoryStore}:{},...t?.mcpManager!==void 0?{mcpManager:t.mcpManager}:{}})}}var y7,b7=y(()=>{"use strict";Ue();cd();AT();Qg();F();Un();rn();en();ml();go();uu();y7=["anthropic","anthropic-direct","openai-codex","openai","openai-compatible","xai","xai-oauth"]});function Fs(){return Lt(pt())}function XT(){return Cf()}function Lt(e,t){return Be(e,t)}function Jd(e){if(!(e===void 0||e.trim()===""))return{explicit:e}}function pt(){let e=k.AFK_MODEL??k.CLAUDE_MODEL;return!e||e.length===0?"medium":e}function Ns(e){let t=k.AFK_DEFAULT_SUBAGENT_MODEL;if(t&&t.length>0)return t;if(typeof e=="string"){let n=ae(e);if(n==="openai-compatible"||n==="xai"||n==="xai-oauth")return e}return"medium"}function Bs(e){if(e===void 0)return;if(e==="adaptive")return{type:"adaptive"};if(e==="disabled")return{type:"disabled"};if(e==="max"||e==="enabled:max")return{type:"enabled",budgetTokens:Number.POSITIVE_INFINITY};let t=/^enabled:(\d+)$/.exec(e);if(t){let n=parseInt(t[1],10);if(Number.isNaN(n))throw new Error(`Invalid thinking budget: ${e}`);return{type:"enabled",budgetTokens:n}}throw new Error(`Invalid --thinking value: ${e}. Expected 'adaptive' | 'disabled' | 'max' | 'enabled:<N>' | 'enabled:max'`)}function Us(e){if(e!==void 0){if(w7.includes(e))return e;throw new Error(`Invalid --effort value: ${e}. Expected one of: ${w7.join(", ")}`)}}function Vd(){return Bs(k.AFK_THINKING)}function Yd(){return Us(k.AFK_EFFORT)}function Xd(e){if(e===void 0)return;if(e===""||e==="NaN")throw new Error(`Invalid --max-budget-usd value: ${JSON.stringify(e)}. Expected a non-negative number.`);let t=Number(e);if(!Number.isFinite(t))throw new Error(`Invalid --max-budget-usd value: ${JSON.stringify(e)}. Expected a non-negative number.`);if(t<0)throw new Error(`Invalid --max-budget-usd value: ${JSON.stringify(e)}. Must be non-negative.`);return t}function uD(){return Xd(k.AFK_MAX_BUDGET_USD)}function dD(){return Xd(k.AFK_TASK_BUDGET)}function Qd(e){if(e===void 0)return;if(e==="max")return Number.POSITIVE_INFINITY;if(e===""||e==="NaN")throw new Error(`Invalid --max-output-tokens value: ${JSON.stringify(e)}. Expected a positive integer or 'max'.`);if(!/^\d+$/.test(e))throw new Error(`Invalid --max-output-tokens value: ${JSON.stringify(e)}. Expected a positive integer or 'max'.`);let t=Number(e);if(!Number.isFinite(t)||!Number.isInteger(t)||t<=0)throw new Error(`Invalid --max-output-tokens value: ${JSON.stringify(e)}. Must be a positive integer.`);return t}function lh(){return Qd(k.AFK_MAX_OUTPUT_TOKENS)}function mUe(e){if(e===void 0)return;let t=Number(e);if(!(!Number.isFinite(t)||t<=0))return Math.floor(t)}function Zd(){return mUe(k.AFK_MAX_TOOL_USE_ITERATIONS)}function S7(e){if(e===null||typeof e!="object")return!1;let t=e;return typeof t.addReadRoot=="function"&&typeof t.addWriteRoot=="function"&&typeof t.revokeRoot=="function"&&typeof t.getGrants=="function"}var w7,yt=y(()=>{"use strict";Ue();kt();F();h7();b7();w7=["low","medium","high","xhigh","max"]});function ep(e=[]){return[...Tn,...Ga,...$t,...Ba,...cu,Kn,"agent","skill","compose",...e]}var QT=y(()=>{"use strict";Un();rn();en();ml();go();uu()});function js(e,t,n="one-shot"){if(!e)return e;let r=[e];return t&&r.push(fUe),hUe.has(n)&&r.push(gUe),r.join(`
1784
1787
 
1785
- `)}var fUe,gUe,hUe,ch=y(()=>{"use strict";fUe='[skill-routing: active]\n\nRoute recurring work through registered skills instead of rolling ad-hoc solutions:\n\n- Before non-trivial implementation (multi-file edits, new features, config/build changes \u2014 anything that writes) \u2192 `/ground-state` first. Do NOT substitute inline `git status`/`get_runtime_state` \u2014 the skill triangulates git + infra + prior-session memory in parallel, which the inline checks miss. If `/ground-state` dispatch fails (depth limit, unavailable), fall back to inline checks AND note the coverage gap.\n- Bugs, failing tests, or regressions \u2192 `/diagnose`\n- High-stakes sub-agent output that will drive edits or commits \u2192 `/shadow-verify` before acting\n- Refactor needing parallel waves \u2192 `/parallelize`\n- Parallel or dependent multi-task work \u2192 `compose` tool (DAG of subagent nodes)\n- Greenfield feature where a written spec would genuinely help (novel scope, multi-day work, or external stakeholders involved) \u2192 `/mint`\n\nDo NOT reach for `/mint` for: bug fixes (use `/diagnose`), refactors with known shape, single-feature edits, work already spec\'d in chat, or anything where the spec/approve pause would feel like ceremony. Implement directly in those cases.\n\nCommon composed sequences \u2014 reach for these when the task shape matches:\n\n- Bug with failing test and non-trivial fix \u2192 `/diagnose` \u2192 `/shadow-verify` on the proposed fix\n- Refactor needing parallel waves \u2192 plan \u2192 `/parallelize` \u2192 build waves\n- Diagnose + fix in parallel \u2192 `compose` with two independent nodes\n- Research \u2192 implement \u2192 verify pipeline \u2192 `compose` with edges: research\u2192implement\u2192verify\n- Multiple independent investigations \u2192 `compose` with N nodes, no edges\n\nReach for context-isolated investigators when the task is exploratory:\n\n- Map an unfamiliar module before editing \u2192 `/gather` or `/research`\n- Re-derive a load-bearing claim independently \u2192 `/shadow-verify`\n- Audit a diff before merge \u2192 `/review`\n- Generate alternatives before committing to a plan \u2192 `/devils-advocate`\n\nOr dispatch a raw `agent` call when no skill matches but the work is parallelizable, verification-heavy, or would otherwise consume substantial inline context.\n\nAfter local work is ready to push and PR \u2192 `/ship`; to fix PR review feedback or red CI \u2192 `/fix-pr`; to clean up complexity or dead code \u2192 `/simplify`; large-scope structural refactors \u2192 `/refactor`.\n\nSkip orchestration for: single-line edits, trivial Q&A, and direct tool calls the user explicitly requested. The goal is leverage, not ceremony. If a skill would add overhead without adding value, don\'t invoke it.\n\nDefault to acting autonomously. `ask_question` is a last resort, not a first move \u2014 every question blocks on the operator, who is often away from keyboard.\n\nBefore you ask, you MUST exhaust the tools you have: read the files, check git, search the codebase and docs, inspect runtime state. If any tool can get you the answer, use the tool \u2014 never ask the operator for something you can discover yourself. When a wrong guess would be cheap or reversible, make a reasonable assumption, proceed, and state the assumption instead of asking.\n\n**Answerability \u2014 a question only helps if a human will actually answer it:**\n\n`surface` (from `get_runtime_state`, view `"self"`) is a partial signal, not a guarantee:\n- `daemon`, or any session started by a scheduler, cron job, or another agent, has no human watching \u2014 never block on `ask_question` here.\n- `cli` is ambiguous: the interactive REPL and the Telegram bot can reach a human, but one-shot `chat` runs and sub-agent forks report the same `cli` and have no elicitation handler \u2014 there `ask_question` returns `{ action: \'decline\' }` instantly.\n- Even when a handler exists, the operator is usually away, so a blocking question can stall until the turn aborts.\n\nSo treat `ask_question` as best-effort: a `decline` or `cancel` result means "no answer is coming," not a failure to abort the task on. When you cannot be sure a human will answer, instead of asking:\n1. **Proceed on a stated assumption** \u2014 pick the most reasonable interpretation, act on it, and record the assumption in your Done/Blocked terminal state for async review.\n2. **Emit a Blocked artifact** \u2014 if no safe assumption exists and proceeding would be irreversible, end the turn with a **Blocked** terminal state naming exactly what the operator must supply before the next run.\n\nReserve `ask_question` for the narrow set of things no tool can resolve: a genuinely ambiguous requirement whose readings lead to materially different work, a decision with significant or irreversible consequences, or context that lives only in the operator\'s head (a preference, a secret, an external constraint):\n\n- Question types: `text` (open-ended), `confirm` (yes/no), `choice` (single pick from list), `multi_choice` (multi-pick), `number` (numeric with optional bounds). When `allow_custom: true`, the result may include `custom_value` instead of `value` \u2014 check `content.custom_value !== undefined` to detect a free-form answer.\n- Ask one focused question at a time. Do NOT ask multiple questions in a single call, and do NOT stack several ask_question calls across a turn \u2014 fold the genuine unknowns into the single most decision-relevant question.\n- Do NOT use when the user has already provided sufficient context \u2014 infer and proceed instead.\n- The result `action` will be `accept` (answered), `cancel` (user interrupted), `decline` (no handler), or `skip` (optional question skipped).\n- `allow_custom` (choice/multi_choice only): opt-in to a free-form entry affordance. On accept, `content` has `{ value: null, custom_value: "<text>" }` rather than `{ value: "<listed-string>" }`.\n- After a `cancel` or `decline`, stop and tell the user what information you need \u2014 do not loop and re-ask.',gUe=`[end-of-turn protocol]
1788
+ `)}var fUe,gUe,hUe,ch=y(()=>{"use strict";fUe='[skill-routing: active]\n\nRoute recurring work through registered skills instead of rolling ad-hoc solutions:\n\n- Before non-trivial implementation (multi-file edits, new features, config/build changes \u2014 anything that writes) \u2192 `/ground-state` first. Do NOT substitute inline `git status`/`get_runtime_state` \u2014 the skill triangulates git + infra + prior-session memory in parallel, which the inline checks miss. If `/ground-state` dispatch fails (depth limit, unavailable), fall back to inline checks AND note the coverage gap.\n- Bugs, failing tests, or regressions \u2192 `/diagnose`\n- High-stakes sub-agent output that will drive edits or commits \u2192 `/shadow-verify` before acting\n- Refactor needing parallel waves \u2192 `/parallelize`\n- Parallel or dependent multi-task work \u2192 `compose` tool (DAG of subagent nodes; minimize the longest dependency chain)\n- Greenfield feature where a written spec would genuinely help (novel scope, multi-day work, or external stakeholders involved) \u2192 `/mint`\n\nDo NOT reach for `/mint` for: bug fixes (use `/diagnose`), refactors with known shape, single-feature edits, work already spec\'d in chat, or anything where the spec/approve pause would feel like ceremony. Implement directly in those cases.\n\nDefault to parallel execution. When a task decomposes into 2+ independent sub-tasks, dispatch them in a single compose wave or parallel agent calls -- do not run them one after another. Sequential dispatch is reserved for chains where an earlier output materially shapes the later prompt.\n\nCommon composed sequences \u2014 reach for these when the task shape matches:\n\n- Bug with failing test and non-trivial fix \u2192 `/diagnose` \u2192 `/shadow-verify` on the proposed fix\n- Refactor needing parallel waves \u2192 plan \u2192 `/parallelize` \u2192 build waves\n- Diagnose + fix in parallel \u2192 `compose` with two independent nodes\n- Research \u2192 implement \u2192 verify pipeline \u2192 `compose` with edges: research\u2192implement\u2192verify\n- Multiple independent investigations \u2192 `compose` with N nodes, no edges\n\nReach for context-isolated investigators when the task is exploratory:\n\n- Map an unfamiliar module before editing \u2192 `/gather` or `/research`\n- Re-derive a load-bearing claim independently \u2192 `/shadow-verify`\n- Audit a diff before merge \u2192 `/review`\n- Generate alternatives before committing to a plan \u2192 `/devils-advocate`\n\nOr dispatch a raw `agent` call when no skill matches but the work is parallelizable, verification-heavy, or would otherwise consume substantial inline context.\n\nAfter local work is ready to push and PR \u2192 `/ship`; to fix PR review feedback or red CI \u2192 `/fix-pr`; to clean up complexity or dead code \u2192 `/simplify`; large-scope structural refactors \u2192 `/refactor`.\n\nSkip orchestration for: single-line edits, trivial Q&A, and direct tool calls the user explicitly requested. The goal is leverage, not ceremony. If a skill would add overhead without adding value, don\'t invoke it.\n\nDefault to acting autonomously. `ask_question` is a last resort, not a first move \u2014 every question blocks on the operator, who is often away from keyboard.\n\nBefore you ask, you MUST exhaust the tools you have: read the files, check git, search the codebase and docs, inspect runtime state. If any tool can get you the answer, use the tool \u2014 never ask the operator for something you can discover yourself. When a wrong guess would be cheap or reversible, make a reasonable assumption, proceed, and state the assumption instead of asking.\n\n**Answerability \u2014 a question only helps if a human will actually answer it:**\n\n`surface` (from `get_runtime_state`, view `"self"`) is a partial signal, not a guarantee:\n- `daemon`, or any session started by a scheduler, cron job, or another agent, has no human watching \u2014 never block on `ask_question` here.\n- `cli` is ambiguous: the interactive REPL and the Telegram bot can reach a human, but one-shot `chat` runs and sub-agent forks report the same `cli` and have no elicitation handler \u2014 there `ask_question` returns `{ action: \'decline\' }` instantly.\n- Even when a handler exists, the operator is usually away, so a blocking question can stall until the turn aborts.\n\nSo treat `ask_question` as best-effort: a `decline` or `cancel` result means "no answer is coming," not a failure to abort the task on. When you cannot be sure a human will answer, instead of asking:\n1. **Proceed on a stated assumption** \u2014 pick the most reasonable interpretation, act on it, and record the assumption in your Done/Blocked terminal state for async review.\n2. **Emit a Blocked artifact** \u2014 if no safe assumption exists and proceeding would be irreversible, end the turn with a **Blocked** terminal state naming exactly what the operator must supply before the next run.\n\nReserve `ask_question` for the narrow set of things no tool can resolve: a genuinely ambiguous requirement whose readings lead to materially different work, a decision with significant or irreversible consequences, or context that lives only in the operator\'s head (a preference, a secret, an external constraint):\n\n- Question types: `text` (open-ended), `confirm` (yes/no), `choice` (single pick from list), `multi_choice` (multi-pick), `number` (numeric with optional bounds). When `allow_custom: true`, the result may include `custom_value` instead of `value` \u2014 check `content.custom_value !== undefined` to detect a free-form answer.\n- Ask one focused question at a time. Do NOT ask multiple questions in a single call, and do NOT stack several ask_question calls across a turn \u2014 fold the genuine unknowns into the single most decision-relevant question.\n- Do NOT use when the user has already provided sufficient context \u2014 infer and proceed instead.\n- The result `action` will be `accept` (answered), `cancel` (user interrupted), `decline` (no handler), or `skip` (optional question skipped).\n- `allow_custom` (choice/multi_choice only): opt-in to a free-form entry affordance. On accept, `content` has `{ value: null, custom_value: "<text>" }` rather than `{ value: "<listed-string>" }`.\n- After a `cancel` or `decline`, stop and tell the user what information you need \u2014 do not loop and re-ask.',gUe=`[end-of-turn protocol]
1786
1789
 
1787
1790
  Every turn must end in one externally identifiable terminal state. AFK users need inspectable artifacts, not ceremony. Write each bullet as a single sentence.
1788
1791
 
@@ -2212,7 +2215,7 @@ ${E}
2212
2215
  ${T}`})}return{fileBlocks:l,warnings:c}}function Dce(e){let t=e.replace(/\s+/g," ").trim();return t.length<=60?t:`${t.slice(0,59)}\u2026`}async function Lce(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}}F();L();F();nt();L();Fl();function Fce(){return{toolStartTimes:new Map,subagentStartTimes:new Map,subagentLabels:new Map}}function Nce(e,t){He()&&(t.pending||e.toolStartTimes.has(t.toolUseId)||e.toolStartTimes.set(t.toolUseId,Date.now()))}function Bce(e,t,n,r){if(!He())return;let o=e.toolStartTimes.get(t.toolUseId),i=o!==void 0?Date.now()-o:void 0;e.toolStartTimes.delete(t.toolUseId);let s=$e(n??"tool"),a=t.isError?m.error("err"):m.success("ok"),l=i!==void 0?` \xB7 ${be(i)}`:"";r.fn(m.dim(` \u25E6 ${s}${l} \xB7 `)+a)}function Uce(e,t,n,r){if(!He())return;let{subagentId:o,agentType:i}=n,s=$e(i??o);if(e.subagentStartTimes.has(o)||(e.subagentStartTimes.set(o,Date.now()),e.subagentLabels.set(o,s),r.fn(m.dim(` \u25E6 worker ${s} started`))),t.type==="done"||t.type==="error"){let l=e.subagentStartTimes.get(o),c=l!==void 0?Date.now()-l:void 0;e.subagentStartTimes.delete(o),e.subagentLabels.delete(o);let u=c!==void 0?` \xB7 ${be(c)}`:"",d=t.type==="error"?m.error("failed"):m.success("done");r.fn(m.dim(` \u25E6 worker ${s}${u} \xB7 `)+d)}}var lA=class{state;writer;ttfb;constructor(t,n){this.state=Fce(),this.writer=t,this.ttfb=n}onToolStart(t){Nce(this.state,t)}onToolResult(t,n){Bce(this.state,t,n,this.writer)}onSubagentEvent(t,n){Uce(this.state,t,n,this.writer)}onFirstContent(t){this.ttfb.waitingLineEmitted&&(this.ttfb.waitingLineEmitted=!1,t.write("\r\x1B[2K"))}};function jce(e){return{startedAt:e,received:!1,waitingLineEmitted:!1}}function Hce(e){return e.received?{}:{turnStartedAt:e.startedAt}}function Wce(e,t,n){let r=t.type==="chunk"&&t.chunk.type==="content"&&!n;return r&&(e.received=!0),r}function Kce(e,t=process.stdout,n){if(!He()||!t.isTTY)return;(e?.fn??console.log)(m.dim(" \u25E6 waiting for response\u2026")),n&&(n.waitingLineEmitted=!0,e&&(n.plainHooks=new lA(e,n)))}ge();L();var p4e=3e3;async function Gce(e,t){if(!e)return t;let n=Date.now();if(n-t<p4e)return t;try{let r=e();r instanceof Promise&&await r}catch(r){qe()&&console.error(" "+m.error("onContextProgress (status refresh) failed:"),r)}return n}L();ge();wt();na();var m4e="Keep waiting \u2014 auto-resume in progress",qce="Switch model / provider (type /model after)",f4e="Stop waiting";async function zce(e){let{event:t,session:n,borrowedCompositor:r,pickerRef:o,completionWriter:i,disposeRendererOnce:s,setPausedState:a,onPauseInterrupt:l}=e;if(a?.(!0),await s(),r&&t.autoResume===!0){let c=new AbortController;o.abort=c;let u=t.resetsAt?t.resetsAt.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit"}):null,d=u?`Keep waiting \u2014 auto-resumes at ${u}`:m4e,p=[m.warning(" \u23F3 Usage limit reached.")+(u?m.dim(` Auto-resumes at ${u}.`):""),m.dim(" Tip: run `claude login` in another terminal to switch account \u2014 this turn resumes on it automatically."),""];On(r,{header:p,options:[d,qce,f4e],signal:c.signal,initialIndex:0}).then(f=>{if(o.abort=null,!f)return;let g=f[0];g===void 0||g===d||(l(),g===qce&&(i??{fn:console.log}).fn(m.dim(" Hint: type /model <name> to switch, then send your message again.")),n.interrupt().catch(h=>{qe()&&console.error(" "+m.error("picker pause-interrupt session.interrupt() failed:"),h)}))}).catch(f=>{qe()&&console.error(" "+m.error("picker promise rejected:"),f)})}else(i??{fn:console.log}).fn(jj({reason:t.reason,...t.resetsAt!==void 0?{resetsAt:t.resetsAt}:{},...t.accountId!==void 0?{accountId:t.accountId}:{},...t.autoResume!==void 0?{autoResume:t.autoResume}:{}}))}lx();async function Jce(e,t,n,r,o="summary",i,s){let a=Gte(e.text,e.attachments);r.onUserMessage&&await Promise.resolve(r.onUserMessage(a)).catch(()=>{}),r.setInFlight(!0);let l=Date.now(),c=jce(l);Kce(i,process.stdout,c),dp(process.stdout,Eh(process.cwd(),!0));let u="",d=0,p=!1,f=!1,g=!1,h=!1,b=!1,w,S=!1,v=!1,E={abort:null},T=0,x=[],C=new Map,I=e.text.startsWith("/")?e.text.split(/[\s:]/)[0]?.slice(1):void 0,A=()=>{let j=r.subagentControl;j?.hasPromotableForeground()&&Lce(j,P,r.onQueuedUserMessage).then(({jobs:q,flushedText:H,flushedPreview:W})=>{let X=(i??{fn:console.log}).fn;for(let D of q)X(m.dim(` \u2192 subagent backgrounded as ${D.jobId}: ${D.label}`));q.some(D=>D.sharesWorktree)&&X(m.warning("\u26A0 Background child is writing to your worktree \u2014 edits may conflict until it finishes")),H!==void 0&&X(m.dim(` \u2192 queued message sent to this turn: ${Dce(W??H)}`))}).catch(()=>{})},P=r.getCompositor?r.getCompositor():null,_=()=>new Lp({out:Np(i),thinkingMode:o,...I?{activeSkillName:I}:{},onCancel:()=>{t.interrupt().catch(j=>{qe()&&console.error(" "+m.error("session.interrupt() failed:"),j)})},...r.subagentControl?{onBackground:A}:{},...s?.history?{history:s.history}:{},...s?.autocompleteState?{autocompleteState:s.autocompleteState}:{},...s?.promptText!==void 0?{promptText:s.promptText}:{},...r.scrollRegion?{scrollRegion:r.scrollRegion}:{},...P?{compositor:P}:{},...r.onStageChange?{onStageChange:r.onStageChange}:{},...Hce(c),...r.addPreviewDiffRef?{addPreviewDiffRef:r.addPreviewDiffRef}:{}}),M=_();r.bashTailSetter&&(r.bashTailSetter.current=(j,q)=>M.setBashOutputTail(j,q));let N=async()=>{if(!h){h=!0,r.bashTailSetter&&(r.bashTailSetter.current=void 0);try{await M.dispose()}catch{}}},O=async()=>{await M.arm();let j=M.getCompositor();if(i&&j){let q=j;i.fn=H=>q.commitAbove(H),i.suppressSubagentCompletion=!0}r.setActiveCompositor?.(j),r.setInterruptNotifier?.(q=>M.setInterrupting(q)),r.rearmStatus?.()};try{P?P.commitAbove(""):console.log(),r.setSoftStopHandler&&r.setSoftStopHandler(()=>{S=!0,M.setSoftStopping(!0),t.interrupt().catch(Z=>{qe()&&console.error(" "+m.error("soft-stop session.interrupt() failed:"),Z)});let K=r.subagentControl;K?.hasActiveForeground()&&K.cancelActiveForeground().catch(Z=>{qe()&&console.error(" "+m.error("soft-stop cancelActiveForeground() failed:"),Z)})}),r.setPauseInterruptHandler&&r.setPauseInterruptHandler(()=>{v=!0,t.interrupt().catch(K=>{qe()&&console.error(" "+m.error("pause-interrupt session.interrupt() failed:"),K)})}),await O(),r.setBackgroundHandler&&r.subagentControl&&r.setBackgroundHandler(A),r.setTaskViewHandler?.(_ce(r));let{fileBlocks:j,warnings:q}=$ce(e.text,{rootDir:process.cwd()});for(let K of q)(i??{fn:console.log}).fn(m.dim(` @-file: ${K}`));if(e.attachments.length>0&&(await t.waitForInitialization(),t.sessionId===void 0))throw new Error("CLI session initialized without a session id");let H=j.length>0||e.attachments.length>0?await Oce(e.text,e.attachments,void 0,j,t.sessionId):e.text,W=t.sendMessageStream(H);await Yu((K,Z)=>{M.process(K,Z),Z&&c.plainHooks?.onSubagentEvent(K,Z)},async()=>{for await(let K of W){if(S||v)break;let Z=Wce(c,K,f);if(K.type==="chunk"&&K.chunk.type==="content"?(u=p?Ace(u,K.chunk.content):u+K.chunk.content,p=!1,f=!0):K.type==="message"&&!f&&(u=K.message.content),K.type==="stream_retry"&&(u=u.slice(0,d),p=u.length>0),K.type==="chunk"&&K.chunk.type==="tool_use_detail"){let ue=K.chunk,ne={toolName:ue.toolName,toolUseId:ue.toolUseId,input:ue.toolInput,...ue.toolInputRaw!==void 0&&{inputRaw:ue.toolInputRaw}};C.set(ue.toolUseId,ne),x.push(ne),c.plainHooks?.onToolStart(ue)}else if(K.type==="chunk"&&K.chunk.type==="tool_result"){let ue=K.chunk;d=u.length,p=!0;let ne=C.get(ue.toolUseId);ne&&(ne.result=ue.content,ne.isError=ue.isError,C.delete(ue.toolUseId)),c.plainHooks?.onToolResult(ue,ne?.toolName),T=await Gce(r.onContextProgress,T)}if(K.type==="paused"){await zce({event:K,session:t,borrowedCompositor:P,pickerRef:E,completionWriter:i,disposeRendererOnce:N,setPausedState:r.setPausedState,onPauseInterrupt:()=>{v=!0}});continue}if(K.type==="resumed"){r.setPausedState?.(!1),E.abort?.abort(),E.abort=null;let ue=K.hotSwapped&&K.accountId?`\u25B6 Resumed on ${K.accountId}`:"\u25B6 Resumed";u="",d=0,p=!1,f=!1,x.length=0,C.clear(),b=!1,w=void 0,g=!1,M=_(),h=!1,await O(),(i??{fn:console.log}).fn(m.success(ue));continue}if(K.type==="error"){await N(),nu(zc(K.error)),g=!0;continue}M.process(K),Z&&(c.plainHooks?.onFirstContent(process.stdout),M.notifyFirstContent()),K.type==="done"&&(b=!0,w=K.metadata)}});let D=!1;if(b&&!S&&!v){let K=xce(M.getPendingBuffer());K>=0?M.stripPendingTerminalState(K):Sy(u)!==null&&(D=!0)}await N();let G=i?i.fn:console.log;if(S){let K=P?P.getPendingCount():0,Z=K>0?` \xB7 ${K} queued`:"";G(m.warning(`\u23F8 Stopped${Z} \u2014 work so far kept.`)+m.dim(" Send a message to continue.")),G("")}if(v&&(G(m.dim("\u25B6 Ending wait \u2014 running your next command\u2026")),G("")),b&&!S&&!v){Wl(n,a,u,w,x),await r.onTurnComplete?.(a,u).catch(()=>{}),up(process.stdout),QZ(process.stdout,"afk: turn complete");let K=ue=>{i?i.fn(ue):console.log(ue)},Z=Sy(u);if(Z&&!D){K(Cce(Z,{durationMs:w?.durationMs,totalCostUsd:w?.totalCostUsd,toolCount:x.length})),K("");let ue=iN(x),ne=bie(x);if(r.onTerminalState)try{r.onTerminalState(Z,{doneHasCorroboratingEvidence:ne,doneEvidenceClassification:ue})}catch{}if(n.permissionMode==="autonomous"){let Ie=Z.kind==="done"&&Nf().verifyDone===!0&&!ne;Sie(Z,void 0,{unverified:Ie})}}if(pB(w,n,K),mB(K,process.stdout),r.onAfterTurn){let ue=r.onAfterTurn();ue instanceof Promise&&await ue.catch(()=>{})}}}catch(j){await N(),g||nu(zc(j))}finally{await N(),dp(process.stdout,Eh(process.cwd(),!1)),i&&(i.fn=i.idleFn,i.suppressSubagentCompletion=!1),r.setActiveCompositor?.(null),r.setInterruptNotifier?.(null),r.setBackgroundHandler?.(null),r.setTaskViewHandler?.(null),r.setSoftStopHandler?.(null),r.setPausedState?.(!1),r.setPauseInterruptHandler?.(null),E.abort?.abort(),E.abort=null,r.setInFlight(!1),r.rearmStatus?.()}}Gs();Nm();var g4e=5e3,h4e=3,y4e="[auto-resume] The background task above has finished. Continue the work it was dispatched for.";async function b4e(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 Vce(e,t,n,r,o,i,s,a){let{contextPane:l,loopStageBar:c,mascotBar:u,healthRail:d,verdictLedger:p,shellPassthrough:f,bgResultNotifier:g}=s,h=null,b=[];e.session.current.waitForInitialization().then(async _=>{qe()&&(h=uR(_)),await Zh(e.session.current),qe()&&(b=AF())}).catch(()=>{});let w=e.initialInput!==void 0?{text:e.initialInput,attachments:[]}:void 0,S,v=!1,E=!1,T;e.clearPendingStopInjection=()=>{T=void 0};let x,C,I,A=(()=>{let _=parseInt(e.options.maxTurns,10);return _>0?_:void 0})(),P=0;for(g.onInjectable=()=>{P>=h4e||!o.isAwaitingInput()||!o.bufferIsEmpty()||(P++,up(process.stdout),w={text:y4e,attachments:[]},o.abortPendingRead())};;){if(P=0,h&&(e.replRenderer.writeLine(h),e.replRenderer.writeLine(""),h=null),b.length>0){for(let D of b)e.replRenderer.writeLine(D);e.replRenderer.writeLine(""),b=[]}let _=f.drainNotifications();for(let{job:D,result:G}of _){let K=G.errorReason===void 0?"\u2713":"\u2717",Z=G.errorReason==="abort"?"killed":G.errorReason==="timeout"?"timed out":G.errorReason==="signal-killed"?"killed by signal":`exit ${G.exitCode??0}`,ue=Math.max(0,Math.round(G.durationMs/100)/10);e.replRenderer.writeLine(m.dim(` ${K} [${D.id}] ${Z} \xB7 ${ue}s \xB7 `)+D.command)}let M=g.drainNotifications();for(let{job:D}of M){let G=D.status==="completed"?"\u2713":D.status==="failed"?"\u2717":"\u2298",K=D.endedAt!==void 0?Math.max(0,Math.round((D.endedAt-D.startedAt)/100)/10):0,Z=ee(D.label,60);e.replRenderer.writeLine(m.dim(` ${G} [${D.jobId}] subagent ${D.status} \xB7 ${K}s \xB7 `)+Z)}let N=l.renderIfChanged(e.stats.sessionId);if(N.length>0){for(let D of N)e.replRenderer.writeLine(D);e.replRenderer.writeLine("")}let O,j;if(w===void 0){let D=await e.session.current.takePendingPlanExitSeed();D!==void 0&&(e.stats.permissionMode=D.mode,w={text:D.message,attachments:[]})}if(w!==void 0){let D=w;w=void 0;let G=Jp(e.stats.permissionMode),K=Vl({buffer:D.text,promptText:G,isTTY:!!process.stdout.isTTY,attachmentSummary:kp([...D.attachments])});e.replRenderer.writeLine(K),O=D.text.trim(),j=D.attachments}else{let D=S;S=void 0;let G=await o.readLine({promptFn:()=>Jp(e.stats.permissionMode),...D!==void 0?{initialBuffer:D}:{},primePromptSuggestion:!0,onSigint:r,onShiftTab:()=>{tA(e.slashCtx).catch(()=>{}),e.statusLine.rearm()}});O=G.text.trim(),j=G.attachments}if(!O&&j.length===0)continue;if(O.startsWith("!")){let D=/^(0|false|off|no)$/i.test(k.AFK_SHELL_PASSTHROUGH??"");if(e.options.shellPassthrough!==!1&&!D&&(v||(v=!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 f.dispatch(O))){e.statusLine.rearm();continue}}let q=!1;if(O.startsWith("/")){let D=await JD(O,e.slashCtx,j);if(D.handled){if(D.result==="exit"){await e.resolveWorktreeDisposition?.(!0),e.rl.close();return}if((O==="/clear"||O.startsWith("/clear "))&&(await t.rotateOnClear(),e.replRenderer.writeLine(m.dim(` transcript: ${t.path()}`)),p.reset(),T=void 0),D.result!==null&&typeof D.result=="object"&&"kind"in D.result&&D.result.kind==="submit"){w={text:D.result.message,attachments:j??[]},e.statusLine.rearm();continue}if(D.result!==null&&typeof D.result=="object"&&"kind"in D.result&&D.result.kind==="prefill"){S=D.result.message,e.statusLine.rearm();continue}e.statusLine.rearm();continue}q=!0}a.push(O),await b4e(e,O);let H=O;if(q){let D=IE(O);if(D){let G=D.name.replace(/^\//,"").split(":").pop()??"";if(G&&Lx(G)){let K={skillName:G,rawArgs:D.args,source:"plugin",capabilities:{compose:!0,subagents:!0}},Z=e.session.current.sessionId,ue=ea(Z),ne=Date.now();U(`[afk trace] preflight.start commandName=${G}`);let Ie=!1,ze=await Zs(K,{cwd:e.stats.cwd??process.cwd(),artifactDir:ue},no=>{qe()&&e.replRenderer.writeLine(m.warning(`\u26A0 preflight(${G}) failed: `)+(no instanceof Error?no.message:String(no)))});Ie=ze!==null,U(`[afk trace] preflight.end commandName=${G} durationMs=${Date.now()-ne} success=${Ie}`),H=Fx(ze?.manifestBlock,O)}}}let W=f.drainInjections();W.length>0&&(H=W+H);let X=g.drainInjections();if(X.length>0&&(H=X+H),T!==void 0&&(H=T+`
2213
2216
 
2214
2217
  `+H,T=void 0),e.hookRegistry)try{let D={event:"UserPromptSubmit",prompt:H,sessionId:e.stats.sessionId},G=await e.hookRegistry.dispatch(D);G.injectContext&&(H=G.injectContext+H)}catch(D){if(D instanceof Ce){e.replRenderer.writeLine(m.warning("\u2298 Turn blocked by hook")+(D.reason?m.dim(`: ${se(D.reason)}`):"")),e.statusLine.rearm();continue}if(D instanceof ho){e.replRenderer.writeLine(m.warning("\u2298 Turn blocked by hook")+m.dim(`: handler timed out after ${D.timeoutMs}ms`)),e.statusLine.rearm();continue}throw D}if(x=C=I=void 0,Jj(),Qj(),await Jce({text:H,attachments:j},e.session.current,e.stats,{setInFlight(D){n.turnInFlight=D},...e.subagentControl?{subagentControl:e.subagentControl}:{},async onUserMessage(D){await t.appendUser(D)},async onQueuedUserMessage(D){await t.appendQueuedUser(D)},async onTurnComplete(D,G){if(await t.appendTurn(D,G),e.stats.sessionId)try{Ks(e.stats)}catch(K){E||(E=!0,e.replRenderer.writeLine(m.warning("\u26A0 ")+"session autosave failed \u2014 this conversation may not be resumable: "+(K instanceof Error?K.message:String(K))))}},async onAfterTurn(){await e.contextSampler.onTurn(e.stats.totalTurns),await e.gitStatusSampler.refresh(),e.statusLine.repaint(vr(e.stats,e.contextSampler,e.gitStatusSampler,A)),e.statusLine.rearm(),c?.repaint("observing"),d?.update(e.stats)},rearmStatus:()=>e.statusLine.rearm(),onTerminalState:(D,G)=>{p?.push(D),x=D.kind,C=G?.doneHasCorroboratingEvidence,I=G?.doneEvidenceClassification},setActiveCompositor:D=>{n.activeCompositor=D,D===null&&n.interruptPickerAbort&&(n.interruptPickerAbort.abort(),n.interruptPickerAbort=null)},setInterruptNotifier:D=>{n.notifyInterrupting=D},scrollRegion:e.statusLine,getCompositor:()=>o.getCompositor(),setBackgroundHandler:D=>o.setBackgroundHandler(D),setTaskViewHandler:D=>o.setTaskViewHandler(D),setSoftStopHandler:i,setPausedState:D=>o.setPausedState(D),setPauseInterruptHandler:D=>o.setPauseInterruptHandler(D),async onContextProgress(){await e.contextSampler.refresh(),e.statusLine.repaint(vr(e.stats,e.contextSampler,e.gitStatusSampler,A)),d?.update(e.stats,e.contextSampler.getRatio())},...c?{onStageChange:(D,G)=>{c.repaint(D),u?.onStage(D,G)}}:{},...e.addPreviewDiffRef?{addPreviewDiffRef:e.addPreviewDiffRef}:{},bashTailSetter:e.bashTailSetter},e.stats.thinkingUi??e.options.thinkingUi,e.completionWriter,o.toRunTurnRefs(Jp(e.stats.permissionMode))),e.hookRegistry)try{let D=await e.hookRegistry.dispatch({event:"Stop",sessionId:e.stats.sessionId,...x!==void 0?{terminalState:x}:{},...C!==void 0?{doneHasCorroboratingEvidence:C}:{},...I!==void 0?{doneEvidenceClassification:I}:{}},void 0,g4e);D.injectContext&&D.injectContext.trim().length>0&&(T=D.injectContext)}catch(D){if(D instanceof Ut)throw D;D instanceof ho?(U("[stop hook] handler timed out"),e.completionWriter.fn(m.dim(" [stop hook] timed out"))):D instanceof Ce?e.completionWriter.fn(m.dim(` [stop hook] blocked: ${se(D.reason??"no reason given")}`)):U("[stop hook] unexpected error: "+String(D))}}}function w4e(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 Yce(e,t,n,r){let o=await Ble(),i=new eA({rl:e.rl,history:o,statusLine:e.statusLine}),s=w4e(k.AFK_SUGGEST_GHOST,e.suggestGhostConfig),a;try{let{installSoftStop:l}=await ace(e,i,n,t,r,s,{getLoopStageBar:()=>a?.loopStageBar,getMascotBar:()=>a?.mascotBar});a=Ece(e,n);let c=a;e.slashCtx.suspendFooter=()=>{c.bgStatusBar.stop(),c.mascotBar.stop(),c.healthRail.stop(),e.statusLine.stop()},e.slashCtx.resumeFooter=()=>{e.statusLine.start(),c.healthRail.start(),c.mascotBar.start(),c.bgStatusBar.start(),c.bgStatusBar.redraw()},await Vce(e,t,n,r,i,l,a,o),await e.resolveWorktreeDisposition?.(!0)}finally{n.tryAbortShellForeground=null,a?.shellPassthrough.drainOnExit(),a?.bgResultNotifier.dispose(),a?.healthRail.stop(),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)}}Pf();Lu();import{execFile as S4e}from"node:child_process";import{dirname as v4e,isAbsolute as k4e,resolve as T4e}from"node:path";import{promisify as E4e}from"node:util";var Xce=E4e(S4e),x4e=3e3,R4e=new Set(["empty","orphaned-dir","orphaned-registration","dead-owner"]);async function A4e(){let t=(await Xce("git",["rev-parse","--git-common-dir"])).stdout.trim();if(!t)throw new Error("Not in a git repository.");let n=k4e(t)?t:T4e(process.cwd(),t);return v4e(n)}async function Qce(e){if(e?.disabled)return{ran:!1,removedCount:0,skippedReason:"disabled"};let t;try{t=await A4e()}catch{return{ran:!1,removedCount:0,skippedReason:"not-in-repo"}}let n,r=new Promise(o=>{n=setTimeout(()=>o("timeout"),x4e)});try{let o=ur({execFile:Xce,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=>R4e.has(c.verdict)&&s.removed.includes(c.path)).length}}catch{return{ran:!1,removedCount:0,skippedReason:"error"}}finally{n&&clearTimeout(n)}}qm();Pf();import{promises as C4e}from"node:fs";import{dirname as _4e,join as tue}from"node:path";import{randomBytes as P4e}from"node:crypto";var I4e=["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(`
2215
- `),Zce=/^[a-z0-9]+(-[a-z0-9]+){1,3}$/,gB=30,M4e=1024,O4e=8e3,$4e="haiku";async function D4e(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=B4e(n,M4e),o=new AbortController,i=setTimeout(()=>o.abort(),t.timeoutMs??O4e),s=t.signal?U4e([t.signal,o.signal]):o.signal,a;try{t.slugGenerator?a=await t.slugGenerator(r,s):a=await Yi({token:t.token,model:t.model??$4e,system:I4e,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=L4e(a);if(l===null)return t.onSkip?.("invalid-slug-output",a.slice(0,60)),null;let c=_4e(t.worktreePath);return await F4e(l,c)}function L4e(e){let t=e.trim().toLowerCase();if(t.length===0)return null;if(Zce.test(t)&&t.length<=gB)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>gB)break;o=s}return Zce.test(o)?o:null}async function F4e(e,t){if(!await N4e(tue(t,e)))return e;let n=P4e(2).toString("hex");return`${e.split("-").slice(0,3).join("-").slice(0,gB-5)}-${n}`}async function N4e(e){try{return await C4e.access(e),!0}catch{return!1}}function B4e(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 U4e(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 nue(e){let t,n,r=tue(e.deferred.repoRoot,".afk-worktrees","unnamed"),o=await D4e(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=`${tS(e.branchPrefix)}${o}`;try{let c=await e.deferred.create(l);return eue(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 eue(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 eue(e,t){e&&e.setCwd(t),j4e(t)}function j4e(e){try{process.chdir(e)}catch{}}yt();Tt();Gc();Ko();B();import{spawn as oue}from"child_process";import{existsSync as iue,mkdirSync as q4e,readFileSync as sue,unlinkSync as rue,writeFileSync as aue}from"fs";import{get as z4e}from"https";import{join as lue}from"path";import{readFileSync as H4e}from"fs";import{dirname as W4e,join as K4e}from"path";import{fileURLToPath as G4e}from"url";function Tr(){try{return"5.211.0"}catch{}try{let e=W4e(G4e(import.meta.url));for(let t of["../../package.json","../package.json"])try{let n=JSON.parse(H4e(K4e(e,t),"utf-8"));if(typeof n.version=="string")return n.version}catch{}}catch{}return"0.0.0-unknown"}L();F();var J4e=64*1024,V4e=10800*1e3,Y4e=800,X4e=3600*1e3,Q4e="update-check.json",Z4e="pending-update.json";function hB(){return lue(va(),Q4e)}function vy(){return lue(va(),Z4e)}function yB(){let e=va();iue(e)||q4e(e,{recursive:!0})}function cue(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 uue(){try{let e=sue(hB(),"utf-8"),t=JSON.parse(e);if(typeof t.latestVersion=="string"&&typeof t.checkedAt=="number")return t}catch{}return null}function due(){try{yB();let e=`
2218
+ `),Zce=/^[a-z0-9]+(-[a-z0-9]+){1,3}$/,gB=30,M4e=1024,O4e=8e3,$4e="haiku";async function D4e(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=B4e(n,M4e),o=new AbortController,i=setTimeout(()=>o.abort(),t.timeoutMs??O4e),s=t.signal?U4e([t.signal,o.signal]):o.signal,a;try{t.slugGenerator?a=await t.slugGenerator(r,s):a=await Yi({token:t.token,model:t.model??$4e,system:I4e,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=L4e(a);if(l===null)return t.onSkip?.("invalid-slug-output",a.slice(0,60)),null;let c=_4e(t.worktreePath);return await F4e(l,c)}function L4e(e){let t=e.trim().toLowerCase();if(t.length===0)return null;if(Zce.test(t)&&t.length<=gB)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>gB)break;o=s}return Zce.test(o)?o:null}async function F4e(e,t){if(!await N4e(tue(t,e)))return e;let n=P4e(2).toString("hex");return`${e.split("-").slice(0,3).join("-").slice(0,gB-5)}-${n}`}async function N4e(e){try{return await C4e.access(e),!0}catch{return!1}}function B4e(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 U4e(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 nue(e){let t,n,r=tue(e.deferred.repoRoot,".afk-worktrees","unnamed"),o=await D4e(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=`${tS(e.branchPrefix)}${o}`;try{let c=await e.deferred.create(l);return eue(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 eue(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 eue(e,t){e&&e.setCwd(t),j4e(t)}function j4e(e){try{process.chdir(e)}catch{}}yt();Tt();Gc();Ko();B();import{spawn as oue}from"child_process";import{existsSync as iue,mkdirSync as q4e,readFileSync as sue,unlinkSync as rue,writeFileSync as aue}from"fs";import{get as z4e}from"https";import{join as lue}from"path";import{readFileSync as H4e}from"fs";import{dirname as W4e,join as K4e}from"path";import{fileURLToPath as G4e}from"url";function Tr(){try{return"5.212.1"}catch{}try{let e=W4e(G4e(import.meta.url));for(let t of["../../package.json","../package.json"])try{let n=JSON.parse(H4e(K4e(e,t),"utf-8"));if(typeof n.version=="string")return n.version}catch{}}catch{}return"0.0.0-unknown"}L();F();var J4e=64*1024,V4e=10800*1e3,Y4e=800,X4e=3600*1e3,Q4e="update-check.json",Z4e="pending-update.json";function hB(){return lue(va(),Q4e)}function vy(){return lue(va(),Z4e)}function yB(){let e=va();iue(e)||q4e(e,{recursive:!0})}function cue(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 uue(){try{let e=sue(hB(),"utf-8"),t=JSON.parse(e);if(typeof t.latestVersion=="string"&&typeof t.checkedAt=="number")return t}catch{}return null}function due(){try{yB();let e=`
2216
2219
  const https = require('https');
2217
2220
  const fs = require('fs');
2218
2221
  const url = 'https://registry.npmjs.org/agent-afk/latest';
@@ -2244,8 +2247,7 @@ Run \`afk i\` then \`/resume\` to list saved sessions.
2244
2247
  Run \`afk i\` then \`/resume\` to list saved sessions.
2245
2248
  `),process.exitCode=1;return}let s=Ve(),a=Sue({cli:r.worktreeOnExit,env:k.AFK_WORKTREE_ON_EXIT,config:s.interactive?.worktreeOnExit,isTTY:!!process.stdout.isTTY,console});r.thinkingUi=cYe(r,s),ao(lo(xb(r.theme,s.theme)));let l=k.AFK_WORKTREE_BRANCH_PREFIX??s.interactive?.worktreeBranchPrefix,c=r.worktreeBase??k.AFK_WORKTREE_BASE??s.interactive?.worktreeBase,u={};l!==void 0&&(u.branchPrefix=l),c!==void 0&&(u.baseRef=c);let d=Object.keys(u).length>0?u:void 0,p=k.AFK_WORKTREE_BOOT_PRUNE==="0",f=await Qce({disabled:p}),g=lYe(r,s),h=Fs(),b=r.worktree===!0&&g&&h!==void 0,w,S,v;if(r.worktree!==void 0)try{b?(v=await wG(d),i.text="Worktree will be named from your first message"):(S=await nS(r.worktree,d),w=S.path,i.text=`Worktree ready at ${S.path} (branch: ${S.branch})`)}catch(ne){i.fail("Worktree setup failed"),V(ne)}let E=f.ran&&f.removedCount>0?`Pruned ${f.removedCount} stale worktree(s). Run /worktree list for details.`:void 0,T=[],x;try{x=await xle(r,{bootWarnings:T,...w!==void 0?{cwd:w}:{}})}catch(ne){i.fail("Invalid options"),eB(T),V(ne)}let C=n.join(" ").trim();if(C&&(x.initialInput=C),v!==void 0&&h!==void 0){let ne=v,Ie=h;x.firstTurnHook=async ze=>{let no=xue({text:"Naming & creating worktree\u2026",...ny}).start(),st=await nue({deferred:ne,message:ze,token:Ie,session:x.session.current,...l!==void 0?{branchPrefix:l}:{}}).finally(()=>no.stop());if(st.status==="created"||st.status==="created-fallback"){S=ne.handle(),x.stats.cwd=st.path;let ro=kc.relative(process.cwd(),st.path)||st.path;if(st.status==="created")console.log(m.dim(" \u21AA worktree: ")+`${ro} `+m.dim(`(branch: ${st.branch})`));else{let Rr=aYe(st.reason,st.detail),Je=Rr!==void 0?m.dim(` \u2014 ${Rr}`):"";console.log(m.dim(" \u21AA worktree: ")+`${ro} `+m.dim(`(branch: ${st.branch})`)+Je)}}else console.warn(m.warning("\u26A0 ")+`Worktree creation failed: ${st.reason}. `+m.dim(`Continuing in ${Rh(process.cwd(),{maxWidth:60})} (no isolation).`))}}let I,A=new AbortController;x.resolveWorktreeDisposition=ne=>{if(I!==void 0)return I;let Ie=ne?x.slashCtx.getCompositor?.()??null:null;return I=vue({...Ie!==null?{picker:ze=>On(Ie,{...ze,signal:A.signal})}:{},isTTY:ne&&!!process.stdout.isTTY,policy:a,turnCount:x.stats.totalTurns,hasWorktree:S!==void 0,console}).then(ze=>{x.worktreeDisposition=ze}),I},ql(async()=>{await x.resolveWorktreeDisposition?.(!1),x.teardownTrustedSkillEvents?.(),je.uninstall(),x.bgSummarizer?.stop(),x.backgroundRegistry.list().filter(Ie=>Ie.status==="running").length>0&&pYe(x.stats.cwd??process.cwd()),await x.backgroundRegistry.cancelAll().catch(()=>{}),await x.session.current.close(),x.mcpManager&&await x.mcpManager.disconnectAll(),x.memoryStore.close(),S!==void 0&&await S.cleanup({force:x.stats.totalTurns===0,disposition:x.worktreeDisposition})}),i.succeed("Session ready"),S!==void 0?console.log(m.dim(" \u21AA worktree: ")+m.dim(Rh(S.path,{maxWidth:60}))+m.dim(` (branch: ${S.branch})`)):v!==void 0&&console.log(m.dim(" \u21AA worktree: named & created from your first message"));let P=await _le(()=>x.stats.model);console.log(m.dim(` transcript: ${P.path()}`)),ql(async()=>{await P.appendEnded()});let _=!1,M=()=>{if(x.stats.totalTurns===0)return;let ne=Ks(x.stats);return _=!0,ne};ql(async()=>{if(!_)try{M()}catch{}});let N={turnInFlight:!1,lastSigintAt:0};x.getInFlight=()=>N.turnInFlight;let O=1500,j=()=>{let ne=Date.now();if(N.tryAbortShellForeground&&N.tryAbortShellForeground()){N.lastSigintAt=ne;return}if(N.turnInFlight){N.lastSigintAt=ne;let Ie=N.activeCompositor;if(N.interruptPickerAbort){N.interruptPickerAbort.abort(),N.interruptPickerAbort=null,x.session.current?.abort("sigint"),x.rl.close();return}if(Ie&&Ie.isArmed()){bue({compositor:Ie,turnState:N,onStop:()=>{N.requestSoftStop?N.requestSoftStop():x.session.current.interrupt().catch(()=>{}),N.notifyInterrupting?.(!0)},onCancel:()=>{x.session.current?.abort("sigint"),x.rl.close()}});return}N.requestSoftStop?N.requestSoftStop():x.session.current.interrupt().catch(()=>{}),N.notifyInterrupting?.(!0);let ze=`
2246
2249
  `+m.info("\u2139 ")+"Press Ctrl+C again to exit.";if(Ie&&Ie.isArmed())try{Ie.commitAbove(ze)}catch{console.log(ze)}else console.log(ze);return}if(ne-N.lastSigintAt<O){x.session.current?.abort("sigint"),x.rl.close();return}N.lastSigintAt=ne,console.log(`
2247
- `+m.info("\u2139 ")+"Press Ctrl+C again (or /exit) to quit.")};process.on("SIGINT",j),ql(async()=>{process.removeListener("SIGINT",j)});let q=!1,H=()=>{if(q)return;q=!0,x.session.current?.abort("sigterm"),A.abort();try{x.rl.close()}catch{}setTimeout(()=>{xE().finally(()=>process.exit(0))},2e3).unref()};process.on("SIGTERM",H),ql(async()=>{process.removeListener("SIGTERM",H)});let W=!1,X=()=>{if(W)return;W=!0,x.session.current?.abort("sighup"),A.abort();try{x.rl.close()}catch{}setTimeout(()=>{xE().finally(()=>process.exit(0))},2e3).unref()};process.on("SIGHUP",X),ql(async()=>{process.removeListener("SIGHUP",X)}),process.stdout.write("\x1B[3J\x1B[2J\x1B[H");let D=1,G=process.stdout.write.bind(process.stdout),K=process.stderr.write.bind(process.stderr),Z=ne=>(typeof ne=="string"?ne:ne instanceof Uint8Array?Buffer.from(ne).toString("utf8"):String(ne)).match(/\n/g)?.length??0,ue=ne=>((Ie,...ze)=>(D+=Z(Ie),ne(Ie,...ze)));process.stdout.write=ue(G),process.stderr.write=ue(K);try{if(mA!==null){let{updateInfo:Ie,pendingMessage:ze}=mA;mA=null,ze!==null&&process.stderr.write(ze),Ie!==null&&cA(Ie)}let ne=x.resumeTarget?`Resuming ${x.resumeTarget.id} \xB7 ${x.stats.totalTurns} prior turn${x.stats.totalTurns===1?"":"s"}`:void 0;console.log(`
2248
- `+Lj({mode:"Interactive Mode",model:x.stats.model,version:Tr(),...S!==void 0?{worktree:S.branch}:{},cwd:w??process.cwd(),...ne!==void 0?{metaLine:ne}:{},hintLine:uYe()})),E!==void 0&&console.log(m.dim(` ${E}`)),x.resumeTarget&&Hx(x.stats,x.completionWriter),Rle({isTTY:!!process.stdout.isTTY,isResume:x.resumeTarget!==void 0}),eB(x.bootWarnings),console.log()}finally{process.stdout.write=G,process.stderr.write=K}x.preArmAnchorRow=D,dp(process.stdout,Eh(process.cwd(),!1)),x.statusLine.start(),x.slashCtx.ui.repaintStatusLine(),x.rl.on("close",async()=>{x.statusLine.stop(),dp(process.stdout,""),dYe(x,S,M),console.log(m.info("\u2139 ")+"Goodbye!"),await xE(),process.exit(0)}),await Yce(x,P,N,j)});Eue(t,e)}function dYe(e,t,n){if(e.stats.totalTurns===0)return;console.log(ce("Session Summary"));let r=[`${e.stats.totalTurns} turn${e.stats.totalTurns===1?"":"s"}`,be(Date.now()-e.stats.sessionStartTime)];r.push(...qi({costUsd:e.stats.totalCostUsd,tokens:e.stats.totalTokens})),console.log(m.dim(" "+r.join(" \xB7 ")));let o=t?kc.basename(t.path):"none";console.log(m.dim(` model: ${e.stats.model} \xB7 worktree: ${o}`));try{let s=e.stats.cwd??process.cwd(),l=SB("git",["diff","--shortstat","HEAD"],{cwd:s,encoding:"utf8",timeout:2e3}).trim();console.log(m.dim(` edits: ${l||"no files changed"}`))}catch{}let i=e.stats.sessionId;try{let s=n();!i&&s&&(i=kc.basename(s,".json"))}catch{}i&&console.log(m.dim(" Continue with: ")+m.brand(qs(i,e.stats.model))),console.log()}function pYe(e){try{let t=SB("git",["diff","--stat","HEAD"],{cwd:e,encoding:"utf8",timeout:2e3}).trim(),n=SB("git",["status","--short"],{cwd:e,encoding:"utf8",timeout:2e3}).trim(),r=["[afk] pre-cancelAll git snapshot (compare after session to detect half-applied edits):"];if(r.push(" git diff --stat HEAD:"),t)for(let o of t.split(`
2250
+ `+m.info("\u2139 ")+"Press Ctrl+C again (or /exit) to quit.")};process.on("SIGINT",j),ql(async()=>{process.removeListener("SIGINT",j)});let q=!1,H=()=>{if(q)return;q=!0,x.session.current?.abort("sigterm"),A.abort();try{x.rl.close()}catch{}setTimeout(()=>{xE().finally(()=>process.exit(0))},2e3).unref()};process.on("SIGTERM",H),ql(async()=>{process.removeListener("SIGTERM",H)});let W=!1,X=()=>{if(W)return;W=!0,x.session.current?.abort("sighup"),A.abort();try{x.rl.close()}catch{}setTimeout(()=>{xE().finally(()=>process.exit(0))},2e3).unref()};process.on("SIGHUP",X),ql(async()=>{process.removeListener("SIGHUP",X)}),process.stdout.write("\x1B[3J\x1B[2J\x1B[H");let D=1,G=process.stdout.write.bind(process.stdout),K=process.stderr.write.bind(process.stderr),Z=ne=>(typeof ne=="string"?ne:ne instanceof Uint8Array?Buffer.from(ne).toString("utf8"):String(ne)).match(/\n/g)?.length??0,ue=ne=>((Ie,...ze)=>(D+=Z(Ie),ne(Ie,...ze)));process.stdout.write=ue(G),process.stderr.write=ue(K);try{if(mA!==null){let{updateInfo:Ie,pendingMessage:ze}=mA;mA=null,ze!==null&&process.stderr.write(ze),Ie!==null&&cA(Ie)}let ne=x.resumeTarget?`Resuming ${x.resumeTarget.id} \xB7 ${x.stats.totalTurns} prior turn${x.stats.totalTurns===1?"":"s"}`:void 0;console.log(Lj({mode:"Interactive Mode",model:x.stats.model,version:Tr(),...S!==void 0?{worktree:S.branch}:{},cwd:w??process.cwd(),...ne!==void 0?{metaLine:ne}:{},hintLine:uYe()})),E!==void 0&&console.log(m.dim(` ${E}`)),x.resumeTarget&&Hx(x.stats,x.completionWriter),Rle({isTTY:!!process.stdout.isTTY,isResume:x.resumeTarget!==void 0}),eB(x.bootWarnings),console.log()}finally{process.stdout.write=G,process.stderr.write=K}x.preArmAnchorRow=D,dp(process.stdout,Eh(process.cwd(),!1)),x.statusLine.start(),x.slashCtx.ui.repaintStatusLine(),x.rl.on("close",async()=>{x.statusLine.stop(),dp(process.stdout,""),dYe(x,S,M),console.log(m.info("\u2139 ")+"Goodbye!"),await xE(),process.exit(0)}),await Yce(x,P,N,j)});Eue(t,e)}function dYe(e,t,n){if(e.stats.totalTurns===0)return;console.log(ce("Session Summary"));let r=[`${e.stats.totalTurns} turn${e.stats.totalTurns===1?"":"s"}`,be(Date.now()-e.stats.sessionStartTime)];r.push(...qi({costUsd:e.stats.totalCostUsd,tokens:e.stats.totalTokens})),console.log(m.dim(" "+r.join(" \xB7 ")));let o=t?kc.basename(t.path):"none";console.log(m.dim(` model: ${e.stats.model} \xB7 worktree: ${o}`));try{let s=e.stats.cwd??process.cwd(),l=SB("git",["diff","--shortstat","HEAD"],{cwd:s,encoding:"utf8",timeout:2e3}).trim();console.log(m.dim(` edits: ${l||"no files changed"}`))}catch{}let i=e.stats.sessionId;try{let s=n();!i&&s&&(i=kc.basename(s,".json"))}catch{}i&&console.log(m.dim(" Continue with: ")+m.brand(qs(i,e.stats.model))),console.log()}function pYe(e){try{let t=SB("git",["diff","--stat","HEAD"],{cwd:e,encoding:"utf8",timeout:2e3}).trim(),n=SB("git",["status","--short"],{cwd:e,encoding:"utf8",timeout:2e3}).trim(),r=["[afk] pre-cancelAll git snapshot (compare after session to detect half-applied edits):"];if(r.push(" git diff --stat HEAD:"),t)for(let o of t.split(`
2249
2251
  `))r.push(` ${o}`);else r.push(" (no uncommitted changes)");if(r.push(" git status --short:"),n)for(let o of n.split(`
2250
2252
  `))r.push(` ${o}`);else r.push(" (working tree clean)");process.stderr.write(r.join(`
2251
2253
  `)+`