agent-afk 5.216.1 → 5.217.0
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.
|
@@ -44,6 +44,20 @@ The only shell permitted is **read-only inspection**: `git diff` / `git show` /
|
|
|
44
44
|
|
|
45
45
|
Never fabricate intent. When none is available the value is the literal `(none supplied)`; agents disclose its absence rather than guess.
|
|
46
46
|
|
|
47
|
+
**Capture prior reviewer feedback (inline, PR targets only).** When the review target is a PR URL or number, fetch existing reviewer feedback from all three GitHub comment stores before dispatching Wave 1:
|
|
48
|
+
|
|
49
|
+
1. Inline review comments (anchored to diff lines): `gh api repos/{owner}/{repo}/pulls/<n>/comments --paginate`.
|
|
50
|
+
2. Review summary bodies (top-level body per review submission): `gh pr view <n> -R {owner}/{repo} --json reviews -q '.reviews[] | {author: .author.login, state: .state, body: .body, submittedAt: .submittedAt}'`.
|
|
51
|
+
3. Conversation comments (issue-level PR comments): `gh pr view <n> -R {owner}/{repo} --json comments -q '.comments[] | {author: .author.login, body: .body, createdAt: .createdAt}'`.
|
|
52
|
+
|
|
53
|
+
Extract `{owner}/{repo}` from the PR URL argument directly, or for bare-number inputs from `gh pr view <n> --json url -q .url`. Pass `-R {owner}/{repo}` on every `gh pr view` call above so cross-repo PR URLs resolve in the correct repository.
|
|
54
|
+
|
|
55
|
+
Filter: drop bot/automation comments (author login contains `[bot]` or body is empty/whitespace). Merge all three stores into a single array, sort by timestamp descending (`created_at` / `submittedAt` / `createdAt`), then cap to the **20 most recent** comments, truncated to a combined **4,096 tokens** to prevent context-window bloat on busy PRs. Identify afk's own prior review comments by the `<!-- agent-afk-review -->` marker.
|
|
56
|
+
|
|
57
|
+
Bundle surviving comments as a **`prior-reviewer-feedback`** block: `[{ source: "inline"|"review"|"conversation", author, body, timestamp, path?, line? }]`. When the PR has no prior comments, set `prior-reviewer-feedback: none`.
|
|
58
|
+
|
|
59
|
+
For non-PR targets (`--staged`, `--head`, working-tree, patch-file, bare commit SHA, branch with no open PR), skip this step and set `prior-reviewer-feedback: not available — non-PR target`.
|
|
60
|
+
|
|
47
61
|
**Pre-fetch file contents at reviewed ref (inline).** After capturing `reviewed_ref` and the diff, and before dispatching any Wave 1 agent, the orchestrator (which has Bash) pre-reads every changed file at the reviewed ref and bundles the results for injection into sub-agent prompts. This is required because Wave 1 and Wave 1.5 agents are `research-agent` instances with no shell — they cannot run `git show` themselves.
|
|
48
62
|
|
|
49
63
|
1. Extract the list of changed files from the diff: `git diff --name-only <base>..<reviewed-ref>` (or parse `--- a/<file>` / `+++ b/<file>` headers from a patch-file diff).
|
|
@@ -63,7 +77,7 @@ When `reviewed_ref` is `unknown` (patch-file input), skip pre-fetch entirely and
|
|
|
63
77
|
- **security · api-compat** — contracts, auth, injection, breaking changes, secret exposure.
|
|
64
78
|
- **correctness · spec-compliance · test-coverage · perf-observability** — logic bugs, regressions, whether the change satisfies its **stated intent** (unmet requirement or unrequested scope creep), missing tests, hot-path perf, logging gaps.
|
|
65
79
|
|
|
66
|
-
Each agent receives: full diff + file tree + triage header + **reviewed ref (SHA)** + the **stated intent** (what the change is meant to accomplish, or `(none supplied)`), the severity rubric, **the `blocking` default table plus its overrides and assignment-order invariant**, and the finding schema. The blocking rules are not optional context: the finding schema mandates a `blocking` value per finding, so an agent that receives the schema without the table is being told to emit a field whose assignment rules it was never given.
|
|
80
|
+
Each agent receives: full diff + file tree + triage header + **reviewed ref (SHA)** + the **stated intent** (what the change is meant to accomplish, or `(none supplied)`), the **`prior-reviewer-feedback`** block (when available), the severity rubric, **the `blocking` default table plus its overrides and assignment-order invariant**, and the finding schema. The blocking rules are not optional context: the finding schema mandates a `blocking` value per finding, so an agent that receives the schema without the table is being told to emit a field whose assignment rules it was never given.
|
|
67
81
|
|
|
68
82
|
**Citation requirement (enforced per agent).** Wave 1 agents cite from the diff and from the **`prefetched-files` block injected by the orchestrator**. They do **not** call `read_file` for ref-anchored verification (the working tree may be on a different branch) and do **not** run git. Centralized verification runs in Wave 1.5, which checks every `blocking`/`critical`/`high` citation **and every `file-state` citation at any severity** against the same pre-fetched content, then drops fabricated ones. Each agent must:
|
|
69
83
|
1. State the reviewed ref it was given in each finding: `ref: <sha>`.
|
|
@@ -92,7 +106,7 @@ If the `Grep` tool is unavailable, tag the finding `[UNVERIFIED: reachability no
|
|
|
92
106
|
|
|
93
107
|
This is the agent's first-line self-check; **Wave 1.5 Check B** independently re-verifies any surviving absence claims against the reviewed ref as a backstop.
|
|
94
108
|
|
|
95
|
-
**Wave 1 — Light review (regime=light, 1 agent, `subagent_type: "research-agent"`).** Single agent covers all dimensions (including spec-compliance). Same `stated-intent` input, rubric, schema, and citation requirement. Through synthesis, the light regime peaks at **1 concurrent sub-agent session** and dispatches **2 in total** (Wave 1 ×1, then Wave 2 ×1, sequential). Its conditional post-synthesis `/shadow-verify` tail dispatches 1–3 verifiers in parallel when qualifying findings surface, making the whole-run budget **peak 1–3 concurrent, 3–5 total (1–3 verifiers)**; the same bound of at most 3 claims in one round with no repeat rounds applies.
|
|
109
|
+
**Wave 1 — Light review (regime=light, 1 agent, `subagent_type: "research-agent"`).** Single agent covers all dimensions (including spec-compliance). Same `stated-intent` input, `prior-reviewer-feedback` block, rubric, schema, and citation requirement. Through synthesis, the light regime peaks at **1 concurrent sub-agent session** and dispatches **2 in total** (Wave 1 ×1, then Wave 2 ×1, sequential). Its conditional post-synthesis `/shadow-verify` tail dispatches 1–3 verifiers in parallel when qualifying findings surface, making the whole-run budget **peak 1–3 concurrent, 3–5 total (1–3 verifiers)**; the same bound of at most 3 claims in one round with no repeat rounds applies.
|
|
96
110
|
|
|
97
111
|
**Wave 1.5 — Citation + absence-claim verification (INLINE — run by the orchestrator, dispatches nothing).** Run after Wave 1 returns, before Wave 2 synthesis. The orchestrator already holds exactly the read-only shell this verification needs (`git show` / `git diff` / `gh pr diff` / `grep` / `rg` — see the shell grant above), so running it inline costs **zero** additional sessions and zero nesting. A shell-less sub-agent here would have to nest a `git-investigator` to run the very commands the orchestrator can already run. Two independent checks:
|
|
98
112
|
|
|
@@ -108,7 +122,15 @@ This is the agent's first-line self-check; **Wave 1.5 Check B** independently re
|
|
|
108
122
|
|
|
109
123
|
Returns a combined verification manifest: `[{type: citation|absence, claim, status, finding_id, evidence?}]`. Findings classified `fabricated` (citation) or `false-absent` (absence) are excluded from Wave 2 input. `diff-only` citations are passed to Wave 2 with a `⚠ diff-only citation — line absent at the reviewed ref` annotation and auto-downgraded one severity tier. `grep-unavailable` absence claims are passed through with their `[UNVERIFIED]` tag intact.
|
|
110
124
|
|
|
111
|
-
**Wave 2 — Synthesis (1 agent, `subagent_type: "research-agent"`).** Receives: Wave 1 findings **after** citation-verification filtering + manifest of dropped/downgraded citations + **the merge-decision rule and its counts format below**. Wave 2 emits the verdict, so it needs that rule for exactly the reason Wave 1 needs the blocking table: an agent told to produce an output whose format and threshold it was never given will improvise both. Dedup by `(file, line_range, dimension)` — keep highest severity on exact match. Flag cross-agent conflicts as `CONFLICT` blocks (surface both rationales; do not auto-resolve).
|
|
125
|
+
**Wave 2 — Synthesis (1 agent, `subagent_type: "research-agent"`).** Receives: Wave 1 findings **after** citation-verification filtering + manifest of dropped/downgraded citations + **the `prior-reviewer-feedback` block** (when available) + **the merge-decision rule and its counts format below**. Wave 2 emits the verdict, so it needs that rule for exactly the reason Wave 1 needs the blocking table: an agent told to produce an output whose format and threshold it was never given will improvise both. Dedup by `(file, line_range, dimension)` — keep highest severity on exact match. Flag cross-agent conflicts as `CONFLICT` blocks (surface both rationales; do not auto-resolve).
|
|
126
|
+
|
|
127
|
+
**Prior-feedback dedup (cross-run).** After intra-run dedup, compare each surviving finding against the `prior-reviewer-feedback` block. Decision rubric:
|
|
128
|
+
- The **diff contains evidence** that the concern was addressed (removed line, added guard, new test) → downgrade finding to `low` severity with `blocking: false` and annotation `[addressed since prior review]`. This is an explicit override of the assignment-order invariant: the pre-downgrade `blocking` value does **not** carry through, because the concern is resolved and surfacing it as blocking defeats the purpose of recognizing the fix. Do not suppress entirely — the reviewer sees the resolution.
|
|
129
|
+
- A prior comment (from afk or a human reviewer) **raised the same concern** and the author **acknowledged and deferred** it (e.g. "I'll fix this in a follow-up") → tag finding `[previously raised — author deferred]` and preserve its original severity. Do not re-raise the argument; note the deferral.
|
|
130
|
+
- A prior comment **raised the same concern** but the issue **persists unchanged in the current diff** → preserve the finding at its earned severity with annotation `[persists from prior review]`. Never suppress a real issue because a prior comment exists.
|
|
131
|
+
- No match in prior feedback → emit the finding unchanged.
|
|
132
|
+
|
|
133
|
+
This rubric is concrete, not discretionary. "Same concern" means the finding and prior comment reference the same file, overlapping line range, and the same class of defect. Semantic similarity alone ("error handling" vs. "missing error handler") is not a match unless file and line range also overlap.
|
|
112
134
|
|
|
113
135
|
**Severity sort order within the blocking list:** findings tagged with semantics matching `invariant violation`, `defeats stated purpose`, `defeats refactor goal`, or `breaks stated contract` sort above all other `high` findings, even those with higher mechanical severity (e.g. test/build hygiene). Within that group, sort by tier (critical → high). Mechanical findings (missing test, build hygiene) sort last within their tier.
|
|
114
136
|
|
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 Nxe,nI=y(()=>{"use strict";Nxe=new Set(["script","style","noscript","template","svg"])});function jxe(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 i2(e,t,n){let r=Math.min(t*2**e,n);return Math.round(Math.random()*r)}function Hxe(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 s2(e,t,n={},r={}){let o=r.retries??3,i=r.baseDelayMs??500,s=r.maxDelayMs??1e4,a=r.sleep??jxe,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(!Uxe.has(d.status)||u===o)return d;let p=Hxe(d,s)??i2(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=i2(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 Uxe,a2=y(()=>{"use strict";ge();Uxe=new Set([429,502,503,504])});import{BlockList as Wxe,isIP as oI}from"node:net";import{lookup as Kxe}from"node:dns/promises";import{Agent as Gxe}from"undici";function c2(){let e=k.AFK_WEB_ALLOW_PRIVATE_HOSTS?.trim().toLowerCase();return e==="1"||e==="true"}function Vxe(e){return e.startsWith("[")&&e.endsWith("]")?e.slice(1,-1):e}function rI(e){let t=oI(e);return t===0?!1:Jxe.check(e,t===4?"ipv4":"ipv6")}async function u2(e){return Kxe(e,{all:!0,verbatim:!0})}async function el(e,t={}){if(t.allowPrivateHosts??c2())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=Vxe(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(oI(r)!==0)return rI(r)?{allowed:!1,reason:o(r,r)}:{allowed:!0};let i=t.lookupFn??u2,s;try{s=await i(r)}catch{return{allowed:!0}}for(let a of s)if(rI(a.address))return{allowed:!1,reason:o(a.address,`${r} (resolved)`)};return{allowed:!0}}async function Kf(e,t={}){let n=await el(e,t);if(!n.allowed)throw new rn(n.reason)}async function as(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<=l2;s++){await Kf(i,o);let a={...n,redirect:"manual",...e===globalThis.fetch&&!(r.allowPrivateHosts??c2())?{dispatcher:Yxe}:{}},l=await s2(e,i,a,r.retry??{});if(!Xxe.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 rn(`too many redirects (>${l2}) starting from ${t}`)}var qxe,zxe,Jxe,rn,Yxe,l2,Xxe,tl=y(()=>{"use strict";F();a2();qxe=[["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]],zxe=[["::",96],["64:ff9b::",96],["fc00::",7],["fe80::",10]],Jxe=(()=>{let e=new Wxe;for(let[t,n]of qxe)e.addSubnet(t,n,"ipv4");for(let[t,n]of zxe)e.addSubnet(t,n,"ipv6");return e})(),rn=class extends Error{constructor(t){super(t),this.name="EgressBlockedError"}};Yxe=new Gxe({connect:{lookup(e,t,n){u2(e).then(r=>{let o=r.find(s=>rI(s.address));if(o!==void 0){n(new rn(`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,oI(i.address))},r=>n(r,"",0))}}});l2=20,Xxe=new Set([301,302,303,307,308])});var sI={};lt(sI,{enforceDomainPolicy:()=>Br,loadBrowserConfig:()=>iI});import{readFileSync as Qxe}from"node:fs";import{join as Zxe}from"path";function eRe(e){let n=e.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function d2(e,t){return eRe(t).test(e)}function rRe(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(tRe.has(t))return!0;if(nRe.has(t))return!1}return!1}function p2(e){return e===void 0||e.trim()===""?[]:e.split(",").map(t=>t.trim().toLowerCase()).filter(t=>t.length>0)}function oRe(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 m2(e){let t=e===void 0||e.trim()===""?"default":e.trim();return Kc(t),t}function iRe(e){if(e===void 0)return!1;let t=e.trim().toLowerCase();return t==="1"||t==="true"||t==="yes"}function sRe(e){try{return Qxe(e,"utf8")}catch(t){if(t.code==="ENOENT")return;throw t}}function aRe(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=m2(t.defaultProfile)),n}function iI(e){let t=e?.env??k,n=e?.readFileSync??sRe,r=e?.surface??t.AGENT_SURFACE,o=rRe(t.AFK_BROWSER_HEADLESS,r),i=p2(t.AFK_BROWSER_ALLOWED_DOMAINS),s=p2(t.AFK_BROWSER_BLOCKED_DOMAINS),a=iRe(t.AFK_BROWSER_DOM_SNAPSHOTS),l=oRe(t.AFK_BROWSER_BACKEND),c=m2(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():Zxe(Tn(),"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=aRe(u,g);return h.configPath=p,h}function Br(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(d2(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return t.allowedDomains.length>0&&!t.allowedDomains.some(o=>d2(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var tRe,nRe,ls=y(()=>{"use strict";F();N();tRe=new Set(["daemon","subagent","telegram","afk"]),nRe=new Set(["repl","interactive","cli"])});import{readFileSync as lRe}from"node:fs";import{join as cRe}from"node:path";import{homedir as uRe}from"node:os";function pRe(e){let t=e??dRe,n;try{n=lRe(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 mRe(e){try{return process.kill(e,0),!0}catch{return!1}}async function fRe(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 aI(e){let t=pRe(e);return t===null?{available:!1,connection:null,reason:"connection file missing or invalid"}:mRe(t.pid)?await fRe(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 dRe,f2=y(()=>{"use strict";dRe=cRe(uRe(),".config","agent-browser","connection.json")});async function g2(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 aI(),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&&gRe.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 aI(),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 gRe,h2=y(()=>{"use strict";f2();gRe=new Set(["daemon","subagent"])});import{createHash as hRe}from"crypto";function y2(e){return!!(e.role==="textbox"&&e.kind==="password"||e.label&&yRe.test(e.label))}function b2(e){return hRe("sha256").update(e,"utf8").digest("hex").slice(0,8)}function w2(e){let t=e.replace(/\s+/g," ").trim();return t.length<=80?t:t.slice(0,77)+"..."}var yRe,gS=y(()=>{"use strict";yRe=/password|secret|token|api[_-]?key|otp|2fa/i});import{randomBytes as bRe}from"crypto";import{mkdir as wRe,stat as SRe,writeFile as vRe}from"fs/promises";import{join as lI}from"path";import{gzip as kRe}from"zlib";import{promisify as TRe}from"util";function ERe(e){return lI(en(e),"browser")}function xRe(e){return lI(ERe(e),"screenshots")}function RRe(){return new Date().toISOString().replace(/[:.]/g,"-")}function ARe(){return bRe(3).toString("hex")}async function $u(e,t,n){if(t.length>S2)throw new Error(`writeScreenshotSidecar: buffer exceeds ${S2} byte cap (received ${t.length} bytes). Refusing to write oversized screenshot.`);let r=xRe(e);await wRe(r,{recursive:!0});let o=`${RRe()}-${ARe()}-${n}.png`,i=lI(r,o);await vRe(i,t);let{size:s}=await SRe(i);return{path:i,bytes:s}}var kdt,S2,cI=y(()=>{"use strict";N();gS();kdt=TRe(kRe);S2=5*1024*1024});var hS,v2=y(()=>{"use strict";ge();hS=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 uI(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 k2(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 dI(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 T2(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(uI)};let i=r[0].id;await dI(e.client,e.tabId,t.action,i,t.value,t.timeoutMs);let s=await e.client.read(e.tabId,{mode:"main"}),a=Br(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 E2=y(()=>{"use strict";ls()});var x2={};lt(x2,{AgentBrowserProvider:()=>pI});var pI,R2=y(()=>{"use strict";ls();cI();v2();E2();pI=class{name="agent-browser";config;client;sessions=new Map;constructor(t,n){this.config=t,this.client=new hS(n)}async open(t){let n=Br(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=Br(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=k2(n.knownElements,t.target);if(r===null){if(t.target.kind==="semantic"){let s=await T2({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 dI(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=Br(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 $u(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(uI),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 $u(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 CRe,readFileSync as _Re}from"node:fs";import{createRequire as PRe}from"node:module";import{dirname as IRe,join as MRe}from"node:path";function _2(e){if(typeof e=="string")return e;let t=[],n=e;for(let r=0;r<$Re&&n instanceof Error;r++)t.push(n.message),n=n.cause;return t.length>0?t.join(" | "):String(e)}function _n(e){let t=_2(e);return C2.some(n=>t.includes(n))}function DRe(){try{let t=PRe(import.meta.url).resolve("playwright/package.json"),n=JSON.parse(_Re(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=MRe(IRe(t),o);return CRe(i)?`node ${/\s/.test(i)?`"${i}"`:i} install chromium`:void 0}catch{return}}function Gf(){return A2??=DRe()??ORe,A2}function mI(e){return e.includes("install chromium")}function ur(e,t){let n=_2(e),r=t?.latched===!0?` ${LRe}`:"";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: ${Gf()}.${o}${r}`}return`browser tools require the optional \`playwright\` peer dependency. Install via: pnpm add playwright (then ${Gf()}). Or pick a different tool.${r}`}function Du(e,t,n=!1){if(!_n(e))return e;let r=e instanceof Error?e.message:String(e);return new Error(`${r}
|
|
438
438
|
|
|
439
|
-
${ur(e,{headless:t,latched:n})}`,{cause:e})}var C2,ORe,$Re,A2,LRe,yS=y(()=>{"use strict";C2=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],ORe="pnpm exec playwright install chromium",$Re=4;LRe="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 nl from"node:fs";import bS from"node:path";import{randomBytes as FRe}from"node:crypto";function NRe(){try{return"5.216.1"}catch{}try{let e=bS.resolve(import.meta.dirname,"../../../package.json"),t=nl.readFileSync(e,"utf8"),n=JSON.parse(t);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var BRe,wS,P2=y(()=>{"use strict";yS();N();ge();BRe=NRe(),wS=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=Du(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=Du(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/${BRe}`}}loadStorageState(t){let n=Gc(t);try{if(!nl.existsSync(n))return;let r=JSON.parse(nl.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=Gc(t);if(!nl.existsSync(r))return;let o=await n.storageState(),i=bS.join(bS.dirname(r),`.${bS.basename(r)}.${process.pid}.${FRe(4).toString("hex")}.tmp`);nl.writeFileSync(i,JSON.stringify(o),{mode:384}),nl.chmodSync(i,384),nl.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 URe}from"node:crypto";function jRe(e){return e?e.replace(/\s+/g," ").trim().slice(0,200):""}function HRe(e,t,n){return`el_${URe("sha256").update(`${e}:${t}:${n}`).digest("hex").slice(0,6)}`}function WRe(e){let t=e.replace(/\s+/g," ").trim(),n=4e3;return t.length<=n?t:t.slice(0,n)+"\u2026[truncated]"}function I2(e){return e.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function O2(e,t){let n=e.role??"",r=e.name??"";M2.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&t.push(e);for(let i of e.children??[])O2(i,t)}async function KRe(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},$2).catch(()=>[])}async function GRe(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},$2).catch(()=>[])}function qRe(e){let n=e.accessibility;return n!==null&&typeof n=="object"?n:null}async function SS(e,t){let n=t.maxElements??80,r=t.includeHidden??!1,o=[],i=qRe(e),s=i?i.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=KRe(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=[],O2(d,b)):(o.push("observation skipped accessibility tree (returned null)"),w=!0,b=(await GRe(e)).filter(M=>M2.has(M.role??"")));let S=new Map;for(let _ of p){let M=I2(_.name),B=S.get(M);(!B||B.bbox.w===0&&_.bbox.w>0)&&S.set(M,_)}let v=b.map(_=>({ax:_,dom:S.get(I2(_.name??""))})),E=r?v:v.filter(_=>_.dom?_.dom.bbox.w>0||_.dom.bbox.h>0:!0);E.sort((_,M)=>{let B=_.dom?.bbox.y??0,O=M.dom?.bbox.y??0;if(B!==O)return B-O;let H=_.dom?.bbox.x??0,q=M.dom?.bbox.x??0;return H-q}),E.length>200&&o.push("page has 200+ interactive elements; consider scoping");let x=E.slice(0,n).map((_,M)=>{let B=_.ax.role??"generic",O=_.ax.name??"",H=HRe(B,O,M),q=_.dom?.bbox??{x:0,y:0,w:0,h:0},W=_.dom?.type??null,K=null;_.ax.value!==void 0&&_.ax.value!==null&&(K=String(_.ax.value)),_.ax.checked!==void 0&&(K=String(_.ax.checked)),y2({role:B,kind:W})&&(K="[redacted]");let Y={disabled:_.ax.disabled??!1};_.ax.checked!==void 0&&(Y.checked=_.ax.checked===!0||_.ax.checked==="mixed"),_.ax.selected!==void 0&&(Y.selected=_.ax.selected),_.ax.expanded!==void 0&&(Y.expanded=_.ax.expanded);let ie;_.dom?.testId?ie=`[data-testid="${_.dom.testId}"]`:_.dom?.id&&(ie=`#${_.dom.id}`);let $={id:H,role:B,label:jRe(O),kind:W,value:K,state:Y,bbox:q};return ie!==void 0&&($.selector=ie),$}),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=WRe(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 M2,$2,D2=y(()=>{"use strict";gS();M2=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);$2="a[href], button, input, select, textarea, [role], [tabindex], label"});async function L2(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 fI(e,t){let n=Math.min(t,5);return(await Promise.all(Array.from({length:n},(o,i)=>L2(e,i)))).filter(o=>o!==null)}async function zRe(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 gI(e,t,n){switch(t.kind){case"element_id":return JRe(e,t,n);case"selector":return VRe(e,t);case"semantic":return YRe(e,t)}}async function JRe(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 fI(o,i);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:s}}async function VRe(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 fI(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${t.selector}]`},candidates:o}}async function YRe(e,t){return t.role!==void 0?XRe(e,t.text,t.role):QRe(e,t.text,t)}async function XRe(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 fI(r,o);return{outcome:"ambiguous_target",query:{text:t,role:n},candidates:i}}async function QRe(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 zRe(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 L2(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 F2=y(()=>{"use strict"});async function hI(e,t,n,r){let o=e.url();if(o===n)return null;let i=Br(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 N2=y(()=>{"use strict";ls()});var bI={};lt(bI,{PlaywrightProvider:()=>yI});function B2(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 yI,wI=y(()=>{"use strict";P2();D2();F2();ls();N2();cI();yI=class{name="playwright";config;launcher;sessions=new Map;constructor(t){this.config=t,this.launcher=new wS(t)}async open(t){let n=Br(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 hI(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 SS(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 SS(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 gI(r,t.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${B2(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 hI(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 SS(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 gI(r,t.target,o.knownElements);if(u.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${B2(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 $u(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 $u(n,o,r);return i}catch{return null}}}});var ol={};lt(ol,{__resetBrowserRegistryForTests:()=>oAe,browserProviderActive:()=>tAe,closeBrowserProvider:()=>vI,getBrowserProvider:()=>eAe,getLastRoutingDecision:()=>rAe,peekBrowserProvider:()=>nAe});function U2(){Promise.resolve(vI()).then(()=>{process.exit(130)})}function j2(){Promise.resolve(vI()).then(()=>{process.exit(143)})}function H2(){Co=null}function ZRe(){vS||(process.on("SIGINT",U2),process.on("SIGTERM",j2),process.on("exit",H2),vS=!0)}function W2(){vS&&(process.removeListener("SIGINT",U2),process.removeListener("SIGTERM",j2),process.removeListener("exit",H2),vS=!1)}async function eAe(e){return Co!==null?Co:(rl!==null||(rl=(async()=>{let t=iI(e),n=e?.surface??(e?.env??{}).AGENT_SURFACE??k.AGENT_SURFACE,r=await g2({config:t,surface:n});SI=r;let o;if(r.backend==="agent-browser"){let{AgentBrowserProvider:i}=await Promise.resolve().then(()=>(R2(),x2)),s=r.availability.connection;o=new i(t,s)}else{let{PlaywrightProvider:i}=await Promise.resolve().then(()=>(wI(),bI));o=new i(t)}return ZRe(),Co=o,rl=null,o})()),rl)}async function vI(){if(Co===null)return;let e=Co;Co=null,rl=null,W2(),await e.shutdown()}function tAe(){return Co!==null}function nAe(){return Co}function rAe(){return SI}function oAe(){Co=null,rl=null,SI=null,W2()}var Co,rl,vS,SI,il=y(()=>{"use strict";ls();h2();F();Co=null,rl=null,vS=!1,SI=null});async function K2(e,t){try{return await n2(e,t)}catch(n){return U("[web/scrape] extraction failed",{url:t,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function uAe(e,t){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(il(),ol)),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(()=>(wI(),bI)),{loadBrowserConfig:s}=await Promise.resolve().then(()=>(ls(),sI)),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 G2(e,t){let n=t.fetchFn??globalThis.fetch,r=t.renderFn??uAe,o=t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{},i=null,s="",a=e,l=null,c=null;try{let d=await as(n,e,{headers:cAe,signal:t.signal},o);l=d.status,a=d.url||e;let p=d.headers.get("content-type")??"";if(d.ok){if(lAe.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(aAe.test(p)&&!sAe.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(s=f,i=await K2(f,a),t.signal.aborted)throw t.signal.reason??new Error("aborted")}}catch(d){if(t.signal.aborted||d instanceof rn||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=tI({html:s,extractedTextLength:i.textLength});return{title:i.title,markdown:i.markdown,finalUrl:a,usedRender:!1,...d!==void 0?{advisory:d}:{}}}try{await Kf(e,o);let d=await r(e,{timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:f=>Kf(f,o)});d.finalUrl!==e&&/^https?:\/\//i.test(d.finalUrl)&&await Kf(d.finalUrl,o);let p=await K2(d.html,d.finalUrl);if(t.signal.aborted)throw t.signal.reason??new Error("aborted");if(i===null||p.textLength>=i.textLength){let f=tI({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 rn)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 sAe,aAe,lAe,cAe,q2=y(()=>{"use strict";r2();nI();tl();ge();sAe=/(text\/html|application\/xhtml\+xml)/i,aAe=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,lAe=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,cAe={"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 mAe(e){let t=e.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let i=await t(dAe,{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),pAe),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 z2(e){return e.exaApiKey!==void 0&&e.exaApiKey.trim()!==""?mAe({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 J2(e,t){if(t.length===0)return`# Search results for "${e}"
|
|
439
|
+
${ur(e,{headless:t,latched:n})}`,{cause:e})}var C2,ORe,$Re,A2,LRe,yS=y(()=>{"use strict";C2=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],ORe="pnpm exec playwright install chromium",$Re=4;LRe="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 nl from"node:fs";import bS from"node:path";import{randomBytes as FRe}from"node:crypto";function NRe(){try{return"5.217.0"}catch{}try{let e=bS.resolve(import.meta.dirname,"../../../package.json"),t=nl.readFileSync(e,"utf8"),n=JSON.parse(t);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var BRe,wS,P2=y(()=>{"use strict";yS();N();ge();BRe=NRe(),wS=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=Du(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=Du(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/${BRe}`}}loadStorageState(t){let n=Gc(t);try{if(!nl.existsSync(n))return;let r=JSON.parse(nl.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=Gc(t);if(!nl.existsSync(r))return;let o=await n.storageState(),i=bS.join(bS.dirname(r),`.${bS.basename(r)}.${process.pid}.${FRe(4).toString("hex")}.tmp`);nl.writeFileSync(i,JSON.stringify(o),{mode:384}),nl.chmodSync(i,384),nl.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 URe}from"node:crypto";function jRe(e){return e?e.replace(/\s+/g," ").trim().slice(0,200):""}function HRe(e,t,n){return`el_${URe("sha256").update(`${e}:${t}:${n}`).digest("hex").slice(0,6)}`}function WRe(e){let t=e.replace(/\s+/g," ").trim(),n=4e3;return t.length<=n?t:t.slice(0,n)+"\u2026[truncated]"}function I2(e){return e.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function O2(e,t){let n=e.role??"",r=e.name??"";M2.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&t.push(e);for(let i of e.children??[])O2(i,t)}async function KRe(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},$2).catch(()=>[])}async function GRe(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},$2).catch(()=>[])}function qRe(e){let n=e.accessibility;return n!==null&&typeof n=="object"?n:null}async function SS(e,t){let n=t.maxElements??80,r=t.includeHidden??!1,o=[],i=qRe(e),s=i?i.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=KRe(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=[],O2(d,b)):(o.push("observation skipped accessibility tree (returned null)"),w=!0,b=(await GRe(e)).filter(M=>M2.has(M.role??"")));let S=new Map;for(let _ of p){let M=I2(_.name),B=S.get(M);(!B||B.bbox.w===0&&_.bbox.w>0)&&S.set(M,_)}let v=b.map(_=>({ax:_,dom:S.get(I2(_.name??""))})),E=r?v:v.filter(_=>_.dom?_.dom.bbox.w>0||_.dom.bbox.h>0:!0);E.sort((_,M)=>{let B=_.dom?.bbox.y??0,O=M.dom?.bbox.y??0;if(B!==O)return B-O;let H=_.dom?.bbox.x??0,q=M.dom?.bbox.x??0;return H-q}),E.length>200&&o.push("page has 200+ interactive elements; consider scoping");let x=E.slice(0,n).map((_,M)=>{let B=_.ax.role??"generic",O=_.ax.name??"",H=HRe(B,O,M),q=_.dom?.bbox??{x:0,y:0,w:0,h:0},W=_.dom?.type??null,K=null;_.ax.value!==void 0&&_.ax.value!==null&&(K=String(_.ax.value)),_.ax.checked!==void 0&&(K=String(_.ax.checked)),y2({role:B,kind:W})&&(K="[redacted]");let Y={disabled:_.ax.disabled??!1};_.ax.checked!==void 0&&(Y.checked=_.ax.checked===!0||_.ax.checked==="mixed"),_.ax.selected!==void 0&&(Y.selected=_.ax.selected),_.ax.expanded!==void 0&&(Y.expanded=_.ax.expanded);let ie;_.dom?.testId?ie=`[data-testid="${_.dom.testId}"]`:_.dom?.id&&(ie=`#${_.dom.id}`);let $={id:H,role:B,label:jRe(O),kind:W,value:K,state:Y,bbox:q};return ie!==void 0&&($.selector=ie),$}),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=WRe(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 M2,$2,D2=y(()=>{"use strict";gS();M2=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);$2="a[href], button, input, select, textarea, [role], [tabindex], label"});async function L2(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 fI(e,t){let n=Math.min(t,5);return(await Promise.all(Array.from({length:n},(o,i)=>L2(e,i)))).filter(o=>o!==null)}async function zRe(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 gI(e,t,n){switch(t.kind){case"element_id":return JRe(e,t,n);case"selector":return VRe(e,t);case"semantic":return YRe(e,t)}}async function JRe(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 fI(o,i);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:s}}async function VRe(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 fI(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${t.selector}]`},candidates:o}}async function YRe(e,t){return t.role!==void 0?XRe(e,t.text,t.role):QRe(e,t.text,t)}async function XRe(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 fI(r,o);return{outcome:"ambiguous_target",query:{text:t,role:n},candidates:i}}async function QRe(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 zRe(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 L2(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 F2=y(()=>{"use strict"});async function hI(e,t,n,r){let o=e.url();if(o===n)return null;let i=Br(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 N2=y(()=>{"use strict";ls()});var bI={};lt(bI,{PlaywrightProvider:()=>yI});function B2(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 yI,wI=y(()=>{"use strict";P2();D2();F2();ls();N2();cI();yI=class{name="playwright";config;launcher;sessions=new Map;constructor(t){this.config=t,this.launcher=new wS(t)}async open(t){let n=Br(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 hI(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 SS(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 SS(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 gI(r,t.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${B2(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 hI(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 SS(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 gI(r,t.target,o.knownElements);if(u.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${B2(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 $u(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 $u(n,o,r);return i}catch{return null}}}});var ol={};lt(ol,{__resetBrowserRegistryForTests:()=>oAe,browserProviderActive:()=>tAe,closeBrowserProvider:()=>vI,getBrowserProvider:()=>eAe,getLastRoutingDecision:()=>rAe,peekBrowserProvider:()=>nAe});function U2(){Promise.resolve(vI()).then(()=>{process.exit(130)})}function j2(){Promise.resolve(vI()).then(()=>{process.exit(143)})}function H2(){Co=null}function ZRe(){vS||(process.on("SIGINT",U2),process.on("SIGTERM",j2),process.on("exit",H2),vS=!0)}function W2(){vS&&(process.removeListener("SIGINT",U2),process.removeListener("SIGTERM",j2),process.removeListener("exit",H2),vS=!1)}async function eAe(e){return Co!==null?Co:(rl!==null||(rl=(async()=>{let t=iI(e),n=e?.surface??(e?.env??{}).AGENT_SURFACE??k.AGENT_SURFACE,r=await g2({config:t,surface:n});SI=r;let o;if(r.backend==="agent-browser"){let{AgentBrowserProvider:i}=await Promise.resolve().then(()=>(R2(),x2)),s=r.availability.connection;o=new i(t,s)}else{let{PlaywrightProvider:i}=await Promise.resolve().then(()=>(wI(),bI));o=new i(t)}return ZRe(),Co=o,rl=null,o})()),rl)}async function vI(){if(Co===null)return;let e=Co;Co=null,rl=null,W2(),await e.shutdown()}function tAe(){return Co!==null}function nAe(){return Co}function rAe(){return SI}function oAe(){Co=null,rl=null,SI=null,W2()}var Co,rl,vS,SI,il=y(()=>{"use strict";ls();h2();F();Co=null,rl=null,vS=!1,SI=null});async function K2(e,t){try{return await n2(e,t)}catch(n){return U("[web/scrape] extraction failed",{url:t,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function uAe(e,t){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(il(),ol)),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(()=>(wI(),bI)),{loadBrowserConfig:s}=await Promise.resolve().then(()=>(ls(),sI)),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 G2(e,t){let n=t.fetchFn??globalThis.fetch,r=t.renderFn??uAe,o=t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{},i=null,s="",a=e,l=null,c=null;try{let d=await as(n,e,{headers:cAe,signal:t.signal},o);l=d.status,a=d.url||e;let p=d.headers.get("content-type")??"";if(d.ok){if(lAe.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(aAe.test(p)&&!sAe.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(s=f,i=await K2(f,a),t.signal.aborted)throw t.signal.reason??new Error("aborted")}}catch(d){if(t.signal.aborted||d instanceof rn||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=tI({html:s,extractedTextLength:i.textLength});return{title:i.title,markdown:i.markdown,finalUrl:a,usedRender:!1,...d!==void 0?{advisory:d}:{}}}try{await Kf(e,o);let d=await r(e,{timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:f=>Kf(f,o)});d.finalUrl!==e&&/^https?:\/\//i.test(d.finalUrl)&&await Kf(d.finalUrl,o);let p=await K2(d.html,d.finalUrl);if(t.signal.aborted)throw t.signal.reason??new Error("aborted");if(i===null||p.textLength>=i.textLength){let f=tI({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 rn)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 sAe,aAe,lAe,cAe,q2=y(()=>{"use strict";r2();nI();tl();ge();sAe=/(text\/html|application\/xhtml\+xml)/i,aAe=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,lAe=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,cAe={"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 mAe(e){let t=e.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let i=await t(dAe,{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),pAe),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 z2(e){return e.exaApiKey!==void 0&&e.exaApiKey.trim()!==""?mAe({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 J2(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 dAe,pAe,V2=y(()=>{"use strict";Fe();dAe="https://api.exa.ai/search",pAe=10});function kS(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 sl=y(()=>{"use strict";yS()});function wAe(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=fAe;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,gAe)}let a=hAe;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,yAe)}return{mode:r,url:o,query:i,timeoutMs:s,maxBytes:a}}function kI(e,t){return Buffer.byteLength(e,"utf8")<=t?{content:e,truncated:!1}:{content:Dr(e,t),truncated:!0}}function SAe(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=wAe(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 el(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 as(t,s.url,h,r)}catch(h){return a.signal.aborted?{content:`web_scrape aborted: ${u()}`,isError:!0}:h instanceof rn?{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=kI(f,s.maxBytes);return{content:g.content,...g.truncated?{truncated:!0}:{}}}if(s.mode==="markdown")try{let p=await G2(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=kI(o2(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 rn)return{content:`web_scrape blocked: ${p.message}`,isError:!0};let f=p instanceof Error?p.message:String(p),g=_n(p)&&!mI(f)?` (the render fallback needs the optional Playwright browser \u2014 run \`${Gf()}\`)`:"";return{content:`web_scrape markdown error: ${f}${g}`,isError:!0}}let d=z2({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:bAe,timeoutMs:s.timeoutMs,signal:a.signal}),f=kI(J2(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 fAe,gAe,hAe,yAe,bAe,Y2,X2=y(()=>{"use strict";q2();V2();tl();wo();nI();sl();fAe=3e4,gAe=12e4,hAe=1e5,yAe=1e6,bAe=10;Y2=SAe()});function TAe(e){return vAe.has(e)?"low":e==="DELETE"?"high":"medium"}function EAe(e){return kAe.has(e)}function AAe(e){let t={};return e.forEach((n,r)=>{let o=r.toLowerCase();RAe.has(o)||xAe.some(i=>o.startsWith(i))||(t[r]=n)}),t}function CAe(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 _Ae(e,t,n){let r=Buffer.byteLength(e,"utf8"),o=e,i=!1;if(r>n&&(o=Dr(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 eq(e){let{url:t,method:n,signal:r,domainCheck:o,recordEffect:i}=e,s=Math.min(e.maxResponseBytes??TI,EI),a={...e.headers},l=e.fetchFn??globalThis.fetch,c=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},u=TAe(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 el(t,c);if(!d.allowed)throw new rn(d.reason);let{serialized:p,inferredContentType:f}=CAe(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=EAe(n)?{retries:2,baseDelayMs:300,maxDelayMs:5e3}:{retries:0},w=Date.now(),S;try{S=await as(l,t,g,{...c,retry:b})}catch(A){throw A instanceof rn,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:B,value:O}=await A.read();if(B||!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}=_Ae(T,E,s),I=AAe(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 tq(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 Q2,Z2,TI,EI,vAe,kAe,xAe,RAe,nq=y(()=>{"use strict";tl();wo();Q2=3e4,Z2=12e4,TI=1e5,EI=1e6,vAe=new Set(["GET","HEAD","OPTIONS"]),kAe=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]);xAe=["set-cookie","x-"],RAe=new Set(["server","via","age","vary","authorization","www-authenticate"])});function PAe(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=tq(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=Q2;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,Z2)}let c=TI;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,EI)}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 IAe(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(()=>(ls(),sI)),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=PAe(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 eq(f)}catch(S){if(l.signal.aborted)return{content:`web_request aborted: ${d()}`,isError:!0};if(S instanceof rn)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 rq,oq=y(()=>{"use strict";nq();tl();Ir();rq=IAe()});import{existsSync as sq,mkdirSync as MAe,readFileSync as OAe,renameSync as $Ae,unlinkSync as DAe,writeFileSync as LAe}from"node:fs";import{dirname as iq,join as FAe}from"node:path";import{randomBytes as NAe}from"node:crypto";function zt(e){let t=e??hb();if(!sq(t))return[];try{let n=OAe(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 Ur(e,t){let n=t??hb();MAe(iq(n),{recursive:!0});let r=FAe(iq(n),`.schedules.json.${process.pid}.${NAe(4).toString("hex")}.tmp`),o=JSON.stringify(e,null,2);try{LAe(r,o,"utf-8"),$Ae(r,n)}catch(i){try{sq(r)&&DAe(r)}catch{}throw i}}function Lu(e,t){let n=zt(t),r=n.map(l=>l.id),o=BAe(e.name),i=UAe(o,r),s=new Date().toISOString(),a={...e,notifyOn:e.notifyOn??"failure",id:i,createdAt:s,updatedAt:s};return n.push(a),Ur(n,t),a}function Fu(e,t){let n=zt(t),r=n.length,o=n.filter(i=>i.id!==e);return o.length===r?!1:(Ur(o,t),!0)}function al(e,t){return zt(t).find(n=>n.id===e)}function BAe(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"")}function UAe(e,t){if(!t.includes(e))return e;let n=2;for(;t.includes(`${e}-${n}`);)n+=1;return`${e}-${n}`}function cs(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 qf=y(()=>{"use strict";N()});import{existsSync as jAe,readFileSync as HAe}from"node:fs";import{join as WAe}from"node:path";async function ft(e,t,n){let r,o;try{let i=WAe(xa("default"),"port");if(!jAe(i))return{synced:!1,detail:"daemon-not-detected (no port file)"};let s=HAe(i,"utf-8").trim(),a=xI(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 xI(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,TS=y(()=>{"use strict";N();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 KAe}from"node:fs";import{readFile as GAe}from"node:fs/promises";var aq,lq,cq,uq,dq=y(()=>{"use strict";qf();N();TS();aq=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=Lu({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}})}},lq=async(e,t)=>{let n=zt();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})))}},cq=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(!KAe(i))return{content:JSON.stringify([])};let s;try{let c=await GAe(i);s=(c.length>1048576?c.subarray(c.length-1048576):c).toString("utf-8")}catch{return{content:JSON.stringify([])}}let a=s.split(`
|
|
@@ -1690,7 +1690,7 @@ All items use \`label: "new-addition"\` (init only creates new entries):
|
|
|
1690
1690
|
- **INV**: Architectural invariants, load-bearing contracts, hard constraints (e.g. "All env vars route through env.ts", "Files capped at 350 LOC").
|
|
1691
1691
|
- **REJ**: Patterns the project has explicitly decided NOT to use, including reverted approaches (e.g. "No raw process.env access", "No inline chalk calls").
|
|
1692
1692
|
- **TST**: Taste/style calls where alternatives exist but one was chosen deliberately (e.g. "Prefer zod schemas at module boundaries", "Use palette.ts for all colors").
|
|
1693
|
-
`,K9="haiku",G9=4096,zT=2e4;zBe=new Set(["new-addition","strengthens","weakens","contradicts"]),JBe=new Set(["INV","REJ","TST"]);Ll=120,W9=500});import{execFileSync as z9}from"node:child_process";import{appendFileSync as J9,mkdirSync as V9}from"node:fs";import{join as Y9}from"node:path";function eD(e={}){return async(t,n)=>{if(t.event!=="SessionEnd")return{};if(t.parentSessionId!==void 0)return{};if(k.AFK_DISABLE_SPINE_UPDATE==="1")return{};let r=t.sessionId??"unknown-session";try{let o=QBe(e.repoRoot??process.cwd()),i=ZBe(o);if(!i.trim())return{};let s=qd(o),a=s?eUe(s):"",l=await V$(i,a,n);if(!l.parsed||l.items.length===0)return{};let c=s??tUe(),u=!1,d=[],p=[];for(let f of l.items){if(f.label==="new-addition"){let g=new Date().toISOString().slice(0,10);lh(c,f.prefix,r,f.description,g),u=!0;continue}if(f.label==="strengthens"){let g=Jd(c,f.existingId);if(g){let b=` (reinforced ${new Date().toISOString().slice(0,10)})
|
|
1693
|
+
`,K9="haiku",G9=4096,zT=2e4;zBe=new Set(["new-addition","strengthens","weakens","contradicts"]),JBe=new Set(["INV","REJ","TST"]);Ll=120,W9=500});import{execFileSync as z9}from"node:child_process";import{appendFileSync as J9,mkdirSync as V9}from"node:fs";import{join as Y9}from"node:path";function eD(e={}){return async(t,n)=>{if(t.event!=="SessionEnd")return{};if(t.parentSessionId!==void 0)return{};if(k.AFK_DISABLE_SPINE_UPDATE==="1")return{};let r=t.sessionId??"unknown-session";try{let o=QBe(e.repoRoot??process.cwd()),i=ZBe(o);if(!i.trim())return{};let s=qd(o),a=s?eUe(s):"",l=await V$(i,a,n);if(!l.parsed||l.items.length===0)return{};let c=s??tUe(),u=!1,d=[],p=[];for(let f of l.items){if(f.label==="new-addition"){let g=new Date().toISOString().slice(0,10);lh(c,f.prefix,r,f.description,g),u=!0;continue}if(f.label==="strengthens"){let g=Jd(c,f.existingId);if(g){let b=` (reinforced ${new Date().toISOString().slice(0,10)})`,w=(g.description.replace(/ \(reinforced \d{4}-\d{2}-\d{2}\)?$/,"")+b).slice(0,Ll);w!==g.description&&(g.description=w,u=!0)}else Z$({type:"strengthens-unresolved",sessionId:r,item:f,ts:new Date().toISOString()});continue}if(f.label==="weakens"){let g=Jd(c,f.existingId);if(g){let b=` (partially weakened ${new Date().toISOString().slice(0,10)})`,w=(g.description.replace(/ \(partially weakened \d{4}-\d{2}-\d{2}\)?$/,"")+b).slice(0,Ll);w!==g.description&&(g.description=w,u=!0),p.push({type:"weakens",sessionId:r,item:f,ts:new Date().toISOString()})}else p.push({type:"weakens-unresolved",sessionId:r,item:f,ts:new Date().toISOString()});continue}f.label==="contradicts"&&d.push(f)}u&&zd(o,c);for(let f of p)Z$(f);for(let f of d)XBe(f,r)}catch(o){try{let i=ce();V9(i,{recursive:!0}),J9(Y9(i,"spine-pending.jsonl"),JSON.stringify({type:"hook-error",sessionId:r,error:o instanceof Error?o.message:String(o),ts:new Date().toISOString()})+`
|
|
1694
1694
|
`,"utf-8")}catch{}}return{}}}function XBe(e,t){Z$({type:"contradicts",sessionId:t,item:e,ts:new Date().toISOString()}),qt(`\u26A0\uFE0F SPINE conflict needs review:
|
|
1695
1695
|
${e.existingId.slice(0,200)}: ${e.existingDescription.slice(0,200)}
|
|
1696
1696
|
Conflict: ${e.description.slice(0,200)}
|
|
@@ -2339,7 +2339,7 @@ ${E}
|
|
|
2339
2339
|
${T}`})}return{fileBlocks:l,warnings:c}}function Xce(e){let t=e.replace(/\s+/g," ").trim();return t.length<=60?t:`${t.slice(0,59)}\u2026`}async function Qce(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();rt();L();Nl();function Zce(){return{toolStartTimes:new Map,subagentStartTimes:new Map,subagentLabels:new Map}}function eue(e,t){He()&&(t.pending||e.toolStartTimes.has(t.toolUseId)||e.toolStartTimes.set(t.toolUseId,Date.now()))}function tue(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 ${Se(i)}`:"";r.fn(m.dim(` \u25E6 ${s}${l} \xB7 `)+a)}function nue(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 ${Se(c)}`:"",d=t.type==="error"?m.error("failed"):m.success("done");r.fn(m.dim(` \u25E6 worker ${s}${u} \xB7 `)+d)}}var fA=class{state;writer;ttfb;constructor(t,n){this.state=Zce(),this.writer=t,this.ttfb=n}onToolStart(t){eue(this.state,t)}onToolResult(t,n){tue(this.state,t,n,this.writer)}onSubagentEvent(t,n){nue(this.state,t,n,this.writer)}onFirstContent(t){this.ttfb.waitingLineEmitted&&(this.ttfb.waitingLineEmitted=!1,t.write("\r\x1B[2K"))}};function rue(e){return{startedAt:e,received:!1,waitingLineEmitted:!1}}function oue(e){return e.received?{}:{turnStartedAt:e.startedAt}}function iue(e,t,n){let r=t.type==="chunk"&&t.chunk.type==="content"&&!n;return r&&(e.received=!0),r}function sue(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 fA(e,n)))}ge();L();var L4e=3e3;async function aue(e,t){if(!e)return t;let n=Date.now();if(n-t<L4e)return t;try{let r=e();r instanceof Promise&&await r}catch(r){ze()&&console.error(" "+m.error("onContextProgress (status refresh) failed:"),r)}return n}L();ge();wt();oa();var F4e="Keep waiting \u2014 auto-resume in progress",lue="Switch model / provider (type /model after)",N4e="Stop waiting";async function cue(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}`:F4e,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."),""];Dn(r,{header:p,options:[d,lue,N4e],signal:c.signal,initialIndex:0}).then(f=>{if(o.abort=null,!f)return;let g=f[0];g===void 0||g===d||(l(),g===lue&&(i??{fn:console.log}).fn(m.dim(" Hint: type /model <name> to switch, then send your message again.")),n.interrupt().catch(h=>{ze()&&console.error(" "+m.error("picker pause-interrupt session.interrupt() failed:"),h)}))}).catch(f=>{ze()&&console.error(" "+m.error("picker promise rejected:"),f)})}else(i??{fn:console.log}).fn(Qj({reason:t.reason,...t.resetsAt!==void 0?{resetsAt:t.resetsAt}:{},...t.accountId!==void 0?{accountId:t.accountId}:{},...t.autoResume!==void 0?{autoResume:t.autoResume}:{}}))}fx();async function uue(e,t,n,r,o="summary",i,s){let a=ane(e.text,e.attachments);r.onUserMessage&&await Promise.resolve(r.onUserMessage(a)).catch(()=>{}),r.setInFlight(!0);let l=Date.now(),c=rue(l);sue(i,process.stdout,c),fp(process.stdout,Ch(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 H=r.subagentControl;H?.hasPromotableForeground()&&Qce(H,P,r.onQueuedUserMessage).then(({jobs:q,flushedText:W,flushedPreview:K})=>{let Y=(i??{fn:console.log}).fn;for(let ie of q)Y(m.dim(` \u2192 subagent backgrounded as ${ie.jobId}: ${ie.label}`));q.some(ie=>ie.sharesWorktree)&&Y(m.warning("\u26A0 Background child is writing to your worktree \u2014 edits may conflict until it finishes")),W!==void 0&&Y(m.dim(` \u2192 queued message sent to this turn: ${Xce(K??W)}`))}).catch(()=>{})},P=r.getCompositor?r.getCompositor():null,_=()=>new Bp({out:jp(i),thinkingMode:o,...I?{activeSkillName:I}:{},onCancel:()=>{t.interrupt().catch(H=>{ze()&&console.error(" "+m.error("session.interrupt() failed:"),H)})},...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}:{},...oue(c),...r.addPreviewDiffRef?{addPreviewDiffRef:r.addPreviewDiffRef}:{}}),M=_();r.bashTailSetter&&(r.bashTailSetter.current=(H,q)=>M.setBashOutputTail(H,q));let B=async()=>{if(!h){h=!0,r.bashTailSetter&&(r.bashTailSetter.current=void 0);try{await M.dispose()}catch{}}},O=async()=>{await M.arm();let H=M.getCompositor();if(i&&H){let q=H;i.fn=W=>q.commitAbove(W),i.suppressSubagentCompletion=!0}r.setActiveCompositor?.(H),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(X=>{ze()&&console.error(" "+m.error("soft-stop session.interrupt() failed:"),X)});let j=r.subagentControl;j?.hasActiveForeground()&&j.cancelActiveForeground().catch(X=>{ze()&&console.error(" "+m.error("soft-stop cancelActiveForeground() failed:"),X)})}),r.setPauseInterruptHandler&&r.setPauseInterruptHandler(()=>{v=!0,t.interrupt().catch(j=>{ze()&&console.error(" "+m.error("pause-interrupt session.interrupt() failed:"),j)})}),await O(),r.setBackgroundHandler&&r.subagentControl&&r.setBackgroundHandler(A),r.setTaskViewHandler?.(Gce(r));let{fileBlocks:H,warnings:q}=Yce(e.text,{rootDir:process.cwd()});for(let j of q)(i??{fn:console.log}).fn(m.dim(` @-file: ${j}`));if(e.attachments.length>0&&(await t.waitForInitialization(),t.sessionId===void 0))throw new Error("CLI session initialized without a session id");let W=H.length>0||e.attachments.length>0?await Vce(e.text,e.attachments,void 0,H,t.sessionId):e.text,K=t.sendMessageStream(W);await Qu((j,X)=>{M.process(j,X),X&&c.plainHooks?.onSubagentEvent(j,X)},async()=>{for await(let j of K){if(S||v)break;let X=iue(c,j,f);if(j.type==="chunk"&&j.chunk.type==="content"?(u=p?Wce(u,j.chunk.content):u+j.chunk.content,p=!1,f=!0,r.onTextDelta?.(j.chunk.content.length)):j.type==="message"&&!f&&(u=j.message.content),j.type==="stream_retry"&&(u=u.slice(0,d),p=u.length>0),j.type==="chunk"&&j.chunk.type==="tool_use_detail"){let le=j.chunk,Z={toolName:le.toolName,toolUseId:le.toolUseId,input:le.toolInput,...le.toolInputRaw!==void 0&&{inputRaw:le.toolInputRaw}};C.set(le.toolUseId,Z),x.push(Z),c.plainHooks?.onToolStart(le)}else if(j.type==="chunk"&&j.chunk.type==="tool_result"){let le=j.chunk;d=u.length,p=!0;let Z=C.get(le.toolUseId);Z&&(Z.result=le.content,Z.isError=le.isError,C.delete(le.toolUseId)),c.plainHooks?.onToolResult(le,Z?.toolName),T=await aue(r.onContextProgress,T)}if(j.type==="paused"){await cue({event:j,session:t,borrowedCompositor:P,pickerRef:E,completionWriter:i,disposeRendererOnce:B,setPausedState:r.setPausedState,onPauseInterrupt:()=>{v=!0}});continue}if(j.type==="resumed"){r.setPausedState?.(!1),E.abort?.abort(),E.abort=null;let le=j.hotSwapped&&j.accountId?`\u25B6 Resumed on ${j.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(le));continue}if(j.type==="error"){await B(),ou(Vc(j.error)),g=!0;continue}M.process(j),X&&(c.plainHooks?.onFirstContent(process.stdout),M.notifyFirstContent()),j.type==="done"&&(b=!0,w=j.metadata)}});let ie=!1;if(b&&!S&&!v){let j=jce(M.getPendingBuffer());j>=0?M.stripPendingTerminalState(j):xy(u)!==null&&(ie=!0)}await B();let $=i?i.fn:console.log;if(S){let j=P?P.getPendingCount():0,X=j>0?` \xB7 ${j} queued`:"";$(m.warning(`\u23F8 Stopped${X} \u2014 work so far kept.`)+m.dim(" Send a message to continue.")),$("")}if(v&&($(m.dim("\u25B6 Ending wait \u2014 running your next command\u2026")),$("")),b&&!S&&!v){Kl(n,a,u,w,x),await r.onTurnComplete?.(a,u).catch(()=>{}),mp(process.stdout),fee(process.stdout,"afk: turn complete");let j=le=>{i?i.fn(le):console.log(le)},X=xy(u);if(X&&!ie){j(Kce(X,{durationMs:w?.durationMs,totalCostUsd:w?.totalCostUsd,toolCount:x.length})),j("");let le=cN(x),Z=Die(x);if(r.onTerminalState)try{r.onTerminalState(X,{doneHasCorroboratingEvidence:Z,doneEvidenceClassification:le})}catch{}if(n.permissionMode==="autonomous"){let Me=X.kind==="done"&&jf().verifyDone===!0&&!Z;Fie(X,void 0,{unverified:Me})}}if(wB(w,n,j),SB(j,process.stdout),r.onAfterTurn){let le=r.onAfterTurn();le instanceof Promise&&await le.catch(()=>{})}}}catch(H){await B(),g||ou(Vc(H))}finally{await B(),fp(process.stdout,Ch(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?.()}}zs();jm();var gA=class{onRepaint;running=!1;smoothedRate=null;lastSampleMs=null;pendingChars=0;lastRepaintMs=0;constructor(t){this.onRepaint=t}start(){this.running=!0,this.smoothedRate=null,this.lastSampleMs=null,this.pendingChars=0,this.lastRepaintMs=0}update(t){if(!this.running||t<=0)return;this.pendingChars+=t;let n=Date.now();if(this.lastSampleMs===null){this.lastSampleMs=n;return}let r=n-this.lastSampleMs;if(r<50)return;if(r>3e3){this.lastSampleMs=n,this.pendingChars=0;return}let o=this.pendingChars/4/r*1e3;this.smoothedRate=this.smoothedRate===null?o:.25*o+(1-.25)*this.smoothedRate,this.lastSampleMs=n,this.pendingChars=0,this.onRepaint&&n-this.lastRepaintMs>=300&&(this.lastRepaintMs=n,this.onRepaint(this.smoothedRate))}getCurrentRate(){return this.running?this.smoothedRate:null}stop(){this.running=!1,this.smoothedRate=null,this.lastSampleMs=null,this.pendingChars=0,this.lastRepaintMs=0,this.onRepaint?.(null)}};L();async function due(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)))}}}var B4e=5e3,U4e=3,j4e="[auto-resume] The background task above has finished. Continue the work it was dispatched for.";async function pue(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 _=>{ze()&&(h=yR(_)),await ry(e.session.current),ze()&&(b=IF())}).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>=U4e||!o.isAwaitingInput()||!o.bufferIsEmpty()||(P++,mp(process.stdout),w={text:j4e,attachments:[]},o.abortPendingRead())};;){if(P=0,h&&(e.replRenderer.writeLine(h),e.replRenderer.writeLine(""),h=null),b.length>0){for(let $ of b)e.replRenderer.writeLine($);e.replRenderer.writeLine(""),b=[]}let _=f.drainNotifications();for(let{job:$,result:j}of _){let X=j.errorReason===void 0?"\u2713":"\u2717",le=j.errorReason==="abort"?"killed":j.errorReason==="timeout"?"timed out":j.errorReason==="signal-killed"?"killed by signal":`exit ${j.exitCode??0}`,Z=Math.max(0,Math.round(j.durationMs/100)/10);e.replRenderer.writeLine(m.dim(` ${X} [${$.id}] ${le} \xB7 ${Z}s \xB7 `)+$.command)}let M=g.drainNotifications();for(let{job:$}of M){let j=$.status==="completed"?"\u2713":$.status==="failed"?"\u2717":"\u2298",X=$.endedAt!==void 0?Math.max(0,Math.round(($.endedAt-$.startedAt)/100)/10):0,le=ee($.label,60);e.replRenderer.writeLine(m.dim(` ${j} [${$.jobId}] subagent ${$.status} \xB7 ${X}s \xB7 `)+le)}let B=l.renderIfChanged(e.stats.sessionId);if(B.length>0){for(let $ of B)e.replRenderer.writeLine($);e.replRenderer.writeLine("")}let O,H;if(w===void 0){let $=await e.session.current.takePendingPlanExitSeed();$!==void 0&&(e.stats.permissionMode=$.mode,w={text:$.message,attachments:[]})}if(w!==void 0){let $=w;w=void 0;let j=Yp(e.stats.permissionMode),X=Yl({buffer:$.text,promptText:j,isTTY:!!process.stdout.isTTY,attachmentSummary:xp([...$.attachments])});e.replRenderer.writeLine(X),O=$.text.trim(),H=$.attachments}else{let $=S;S=void 0;let j=await o.readLine({promptFn:()=>Yp(e.stats.permissionMode),...$!==void 0?{initialBuffer:$}:{},primePromptSuggestion:!0,onSigint:r,onShiftTab:()=>{aA(e.slashCtx).catch(()=>{}),e.statusLine.rearm()}});O=j.text.trim(),H=j.attachments}if(!O&&H.length===0)continue;if(O.startsWith("!")){let $=/^(0|false|off|no)$/i.test(k.AFK_SHELL_PASSTHROUGH??"");if(e.options.shellPassthrough!==!1&&!$&&(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 $=await QD(O,e.slashCtx,H);if($.handled){if($.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),$.result!==null&&typeof $.result=="object"&&"kind"in $.result&&$.result.kind==="submit"){w={text:$.result.message,attachments:H??[]},e.statusLine.rearm();continue}if($.result!==null&&typeof $.result=="object"&&"kind"in $.result&&$.result.kind==="prefill"){S=$.result.message,e.statusLine.rearm();continue}e.statusLine.rearm();continue}q=!0}a.push(O),await due(e,O);let W=O;if(q){let $=LE(O);if($){let j=$.name.replace(/^\//,"").split(":").pop()??"";if(j&&Wx(j)){let X={skillName:j,rawArgs:$.args,source:"plugin",capabilities:{compose:!0,subagents:!0}},le=e.session.current.sessionId,Z=na(le),Me=Date.now();U(`[afk trace] preflight.start commandName=${j}`);let Je=!1,Xo=await ta(X,{cwd:e.stats.cwd??process.cwd(),artifactDir:Z},Ge=>{ze()&&e.replRenderer.writeLine(m.warning(`\u26A0 preflight(${j}) failed: `)+(Ge instanceof Error?Ge.message:String(Ge)))});Je=Xo!==null,U(`[afk trace] preflight.end commandName=${j} durationMs=${Date.now()-Me} success=${Je}`),W=Kx(Xo?.manifestBlock,O)}}}let K=f.drainInjections();K.length>0&&(W=K+W);let Y=g.drainInjections();if(Y.length>0&&(W=Y+W),T!==void 0&&(W=T+`
|
|
2340
2340
|
|
|
2341
2341
|
`+W,T=void 0),e.hookRegistry)try{let $={event:"UserPromptSubmit",prompt:W,sessionId:e.stats.sessionId},j=await e.hookRegistry.dispatch($);j.injectContext&&(W=j.injectContext+W)}catch($){if($ instanceof Ce){e.replRenderer.writeLine(m.warning("\u2298 Turn blocked by hook")+($.reason?m.dim(`: ${se($.reason)}`):"")),e.statusLine.rearm();continue}if($ instanceof yo){e.replRenderer.writeLine(m.warning("\u2298 Turn blocked by hook")+m.dim(`: handler timed out after ${$.timeoutMs}ms`)),e.statusLine.rearm();continue}throw $}x=C=I=void 0,i1(),c1();let ie=new gA($=>{e.statusLine.repaint({...Xn(e.stats,e.contextSampler,e.gitStatusSampler,A),tokPerSec:$??void 0})});if(ie.start(),await uue({text:W,attachments:H},e.session.current,e.stats,{setInFlight($){n.turnInFlight=$},...e.subagentControl?{subagentControl:e.subagentControl}:{},async onUserMessage($){await t.appendUser($)},async onQueuedUserMessage($){await t.appendQueuedUser($)},async onTurnComplete($,j){if(await t.appendTurn($,j),e.stats.sessionId)try{qs(e.stats)}catch(X){E||(E=!0,e.replRenderer.writeLine(m.warning("\u26A0 ")+"session autosave failed \u2014 this conversation may not be resumable: "+(X instanceof Error?X.message:String(X))))}},async onAfterTurn(){ie.stop(),await e.contextSampler.onTurn(e.stats.totalTurns),await e.gitStatusSampler.refresh(),e.statusLine.repaint(Xn(e.stats,e.contextSampler,e.gitStatusSampler,A)),e.statusLine.rearm(),c?.repaint("observing"),d?.update(e.stats)},rearmStatus:()=>e.statusLine.rearm(),onTerminalState:($,j)=>{p?.push($),x=$.kind,C=j?.doneHasCorroboratingEvidence,I=j?.doneEvidenceClassification},setActiveCompositor:$=>{n.activeCompositor=$,$===null&&n.interruptPickerAbort&&(n.interruptPickerAbort.abort(),n.interruptPickerAbort=null)},setInterruptNotifier:$=>{n.notifyInterrupting=$},scrollRegion:e.statusLine,getCompositor:()=>o.getCompositor(),setBackgroundHandler:$=>o.setBackgroundHandler($),setTaskViewHandler:$=>o.setTaskViewHandler($),setSoftStopHandler:i,setPausedState:$=>o.setPausedState($),setPauseInterruptHandler:$=>o.setPauseInterruptHandler($),async onContextProgress(){await e.contextSampler.refresh(),e.statusLine.repaint(Xn(e.stats,e.contextSampler,e.gitStatusSampler,A)),d?.update(e.stats,e.contextSampler.getRatio())},...c?{onStageChange:($,j)=>{c.repaint($),u?.onStage($,j)}}:{},...e.addPreviewDiffRef?{addPreviewDiffRef:e.addPreviewDiffRef}:{},bashTailSetter:e.bashTailSetter,onTextDelta:$=>ie.update($)},e.stats.thinkingUi??e.options.thinkingUi,e.completionWriter,o.toRunTurnRefs(Yp(e.stats.permissionMode))),e.hookRegistry)try{let $=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,B4e);$.injectContext&&$.injectContext.trim().length>0&&(T=$.injectContext)}catch($){if($ instanceof Ht)throw $;$ instanceof yo?(U("[stop hook] handler timed out"),e.completionWriter.fn(m.dim(" [stop hook] timed out"))):$ instanceof Ce?e.completionWriter.fn(m.dim(` [stop hook] blocked: ${se($.reason??"no reason given")}`)):U("[stop hook] unexpected error: "+String($))}}}function H4e(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 mue(e,t,n,r){let o=await tce(),i=new sA({rl:e.rl,history:o,statusLine:e.statusLine}),s=H4e(k.AFK_SUGGEST_GHOST,e.suggestGhostConfig),a;try{let{installSoftStop:l}=await Tce(e,i,n,t,r,s,{getLoopStageBar:()=>a?.loopStageBar,getMascotBar:()=>a?.mascotBar});a=Uce(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 pue(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)}}Of();Nu();import{execFile as W4e}from"node:child_process";import{dirname as K4e,isAbsolute as G4e,resolve as q4e}from"node:path";import{promisify as z4e}from"node:util";var fue=z4e(W4e),J4e=3e3,V4e=new Set(["empty","orphaned-dir","orphaned-registration","dead-owner"]);async function Y4e(){let t=(await fue("git",["rev-parse","--git-common-dir"])).stdout.trim();if(!t)throw new Error("Not in a git repository.");let n=G4e(t)?t:q4e(process.cwd(),t);return K4e(n)}async function gue(e){if(e?.disabled)return{ran:!1,removedCount:0,skippedReason:"disabled"};let t;try{t=await Y4e()}catch{return{ran:!1,removedCount:0,skippedReason:"not-in-repo"}}let n,r=new Promise(o=>{n=setTimeout(()=>o("timeout"),J4e)});try{let o=pr({execFile:fue,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=>V4e.has(c.verdict)&&s.removed.includes(c.path)).length}}catch{return{ran:!1,removedCount:0,skippedReason:"error"}}finally{n&&clearTimeout(n)}}Vm();Of();import{promises as X4e}from"node:fs";import{dirname as Q4e,join as bue}from"node:path";import{randomBytes as Z4e}from"node:crypto";var eYe=["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(`
|
|
2342
|
-
`),hue=/^[a-z0-9]+(-[a-z0-9]+){1,3}$/,kB=30,tYe=1024,nYe=8e3,rYe="haiku";async function oYe(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=lYe(n,tYe),o=new AbortController,i=setTimeout(()=>o.abort(),t.timeoutMs??nYe),s=t.signal?cYe([t.signal,o.signal]):o.signal,a;try{t.slugGenerator?a=await t.slugGenerator(r,s):a=await ti({token:t.token,model:t.model??rYe,system:eYe,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=iYe(a);if(l===null)return t.onSkip?.("invalid-slug-output",a.slice(0,60)),null;let c=Q4e(t.worktreePath);return await sYe(l,c)}function iYe(e){let t=e.trim().toLowerCase();if(t.length===0)return null;if(hue.test(t)&&t.length<=kB)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>kB)break;o=s}return hue.test(o)?o:null}async function sYe(e,t){if(!await aYe(bue(t,e)))return e;let n=Z4e(2).toString("hex");return`${e.split("-").slice(0,3).join("-").slice(0,kB-5)}-${n}`}async function aYe(e){try{return await X4e.access(e),!0}catch{return!1}}function lYe(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 cYe(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 wue(e){let t,n,r=bue(e.deferred.repoRoot,".afk-worktrees","unnamed"),o=await oYe(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=`${aS(e.branchPrefix)}${o}`;try{let c=await e.deferred.create(l);return yue(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 yue(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 yue(e,t){e&&e.setCwd(t),uYe(t)}function uYe(e){try{process.chdir(e)}catch{}}yt();Tt();zc();Go();N();import{spawn as vue}from"child_process";import{existsSync as kue,mkdirSync as gYe,readFileSync as Tue,unlinkSync as Sue,writeFileSync as Eue}from"fs";import{get as hYe}from"https";import{join as xue}from"path";import{readFileSync as dYe}from"fs";import{dirname as pYe,join as mYe}from"path";import{fileURLToPath as fYe}from"url";function Qn(){try{return"5.
|
|
2342
|
+
`),hue=/^[a-z0-9]+(-[a-z0-9]+){1,3}$/,kB=30,tYe=1024,nYe=8e3,rYe="haiku";async function oYe(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=lYe(n,tYe),o=new AbortController,i=setTimeout(()=>o.abort(),t.timeoutMs??nYe),s=t.signal?cYe([t.signal,o.signal]):o.signal,a;try{t.slugGenerator?a=await t.slugGenerator(r,s):a=await ti({token:t.token,model:t.model??rYe,system:eYe,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=iYe(a);if(l===null)return t.onSkip?.("invalid-slug-output",a.slice(0,60)),null;let c=Q4e(t.worktreePath);return await sYe(l,c)}function iYe(e){let t=e.trim().toLowerCase();if(t.length===0)return null;if(hue.test(t)&&t.length<=kB)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>kB)break;o=s}return hue.test(o)?o:null}async function sYe(e,t){if(!await aYe(bue(t,e)))return e;let n=Z4e(2).toString("hex");return`${e.split("-").slice(0,3).join("-").slice(0,kB-5)}-${n}`}async function aYe(e){try{return await X4e.access(e),!0}catch{return!1}}function lYe(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 cYe(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 wue(e){let t,n,r=bue(e.deferred.repoRoot,".afk-worktrees","unnamed"),o=await oYe(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=`${aS(e.branchPrefix)}${o}`;try{let c=await e.deferred.create(l);return yue(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 yue(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 yue(e,t){e&&e.setCwd(t),uYe(t)}function uYe(e){try{process.chdir(e)}catch{}}yt();Tt();zc();Go();N();import{spawn as vue}from"child_process";import{existsSync as kue,mkdirSync as gYe,readFileSync as Tue,unlinkSync as Sue,writeFileSync as Eue}from"fs";import{get as hYe}from"https";import{join as xue}from"path";import{readFileSync as dYe}from"fs";import{dirname as pYe,join as mYe}from"path";import{fileURLToPath as fYe}from"url";function Qn(){try{return"5.217.0"}catch{}try{let e=pYe(fYe(import.meta.url));for(let t of["../../package.json","../package.json"])try{let n=JSON.parse(dYe(mYe(e,t),"utf-8"));if(typeof n.version=="string")return n.version}catch{}}catch{}return"0.0.0-unknown"}L();F();var yYe=64*1024,bYe=10800*1e3,wYe=800,SYe=3600*1e3,vYe="update-check.json",kYe="pending-update.json";function TB(){return xue(Ea(),vYe)}function Ry(){return xue(Ea(),kYe)}function EB(){let e=Ea();kue(e)||gYe(e,{recursive:!0})}function Rue(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 Aue(){try{let e=Tue(TB(),"utf-8"),t=JSON.parse(e);if(typeof t.latestVersion=="string"&&typeof t.checkedAt=="number")return t}catch{}return null}function Cue(){try{EB();let e=`
|
|
2343
2343
|
const https = require('https');
|
|
2344
2344
|
const fs = require('fs');
|
|
2345
2345
|
const url = 'https://registry.npmjs.org/agent-afk/latest';
|
package/dist/index.mjs
CHANGED
|
@@ -280,7 +280,7 @@ Send a message to start one, or /new for a fresh session.`}function P_(t){return
|
|
|
280
280
|
|
|
281
281
|
${e}`}var K1,pm=m(()=>{"use strict";K1=new Set(["script","style","noscript","template","svg"])});function X1(t,e){return new Promise((n,r)=>{if(e?.aborted){r(e.reason??new Error("aborted"));return}let o=()=>{clearTimeout(s),r(e?.reason??new Error("aborted"))},s=setTimeout(()=>{e?.removeEventListener("abort",o),n()},t);e?.addEventListener("abort",o,{once:!0})})}function H_(t,e,n){let r=Math.min(e*2**t,n);return Math.round(Math.random()*r)}function z1(t,e){let n=t.headers.get("retry-after");if(n===null)return null;let r=Number(n.trim());return!Number.isFinite(r)||r<0?null:Math.min(r*1e3,e)}async function W_(t,e,n={},r={}){let o=r.retries??3,s=r.baseDelayMs??500,i=r.maxDelayMs??1e4,a=r.sleep??X1,c=n.signal??void 0,l;for(let d=0;d<=o;d++){if(c?.aborted)throw c.reason??new Error("aborted");try{let u=await t(e,n);if(!q1.has(u.status)||d===o)return u;let p=z1(u,i)??H_(d,s,i);D("[web/retryFetch] retrying",{url:e,attempt:d,status:u.status,waitMs:p}),await u.body?.cancel().catch(()=>{}),await a(p,c)}catch(u){if(c?.aborted||(l=u,d===o))throw u;let p=H_(d,s,i);D("[web/retryFetch] retrying after error",{url:e,attempt:d,waitMs:p}),await a(p,c)}}throw l??new Error("retryFetch: exhausted without a result")}var q1,K_=m(()=>{"use strict";Q();q1=new Set([429,502,503,504])});import{BlockList as J1,isIP as mm}from"node:net";import{lookup as V1}from"node:dns/promises";import{Agent as Y1}from"undici";function q_(){let t=w.AFK_WEB_ALLOW_PRIVATE_HOSTS?.trim().toLowerCase();return t==="1"||t==="true"}function tK(t){return t.startsWith("[")&&t.endsWith("]")?t.slice(1,-1):t}function fm(t){let e=mm(t);return e===0?!1:eK.check(t,e===4?"ipv4":"ipv6")}async function X_(t){return V1(t,{all:!0,verbatim:!0})}async function Jn(t,e={}){if(e.allowPrivateHosts??q_())return{allowed:!0};let n;try{n=new URL(t)}catch{return{allowed:!1,reason:`"${t}" is not a valid absolute URL`}}if(n.protocol!=="http:"&&n.protocol!=="https:")return{allowed:!1,reason:`protocol "${n.protocol}" not supported (http/https only)`};let r=tK(n.hostname),o=(a,c)=>`refusing to fetch ${c} \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(mm(r)!==0)return fm(r)?{allowed:!1,reason:o(r,r)}:{allowed:!0};let s=e.lookupFn??X_,i;try{i=await s(r)}catch{return{allowed:!0}}for(let a of i)if(fm(a.address))return{allowed:!1,reason:o(a.address,`${r} (resolved)`)};return{allowed:!0}}async function Ws(t,e={}){let n=await Jn(t,e);if(!n.allowed)throw new ve(n.reason)}async function an(t,e,n={},r={}){let o={...r.lookupFn!==void 0?{lookupFn:r.lookupFn}:{},...r.allowPrivateHosts!==void 0?{allowPrivateHosts:r.allowPrivateHosts}:{}},s=e;for(let i=0;i<=G_;i++){await Ws(s,o);let a={...n,redirect:"manual",...t===globalThis.fetch&&!(r.allowPrivateHosts??q_())?{dispatcher:nK}:{}},c=await W_(t,s,a,r.retry??{});if(!rK.has(c.status))return c;let l=c.headers.get("location");if(l===null||l.trim()==="")return c;let d;try{d=new URL(l,c.url||s).toString()}catch{return c}await c.body?.cancel().catch(()=>{}),s=d}throw new ve(`too many redirects (>${G_}) starting from ${e}`)}var Q1,Z1,eK,ve,nK,G_,rK,Vn=m(()=>{"use strict";P();K_();Q1=[["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]],Z1=[["::",96],["64:ff9b::",96],["fc00::",7],["fe80::",10]],eK=(()=>{let t=new J1;for(let[e,n]of Q1)t.addSubnet(e,n,"ipv4");for(let[e,n]of Z1)t.addSubnet(e,n,"ipv6");return t})(),ve=class extends Error{constructor(e){super(e),this.name="EgressBlockedError"}};nK=new Y1({connect:{lookup(t,e,n){X_(t).then(r=>{let o=r.find(i=>fm(i.address));if(o!==void 0){n(new ve(`refusing to connect to ${t} (resolved) \u2014 internal/private address ${o.address} (loopback, link-local, cloud metadata, or RFC1918 space). Set AFK_WEB_ALLOW_PRIVATE_HOSTS=1 to allow private-host access.`),"",0);return}let s=r[0];if(s===void 0){n(new Error(`DNS lookup returned no addresses for ${t}`),"",0);return}n(null,s.address,mm(s.address))},r=>n(r,"",0))}}});G_=20,rK=new Set([301,302,303,307,308])});var hm={};qo(hm,{enforceDomainPolicy:()=>ft,loadBrowserConfig:()=>gm});import{readFileSync as oK}from"node:fs";import{join as sK}from"path";function iK(t){let n=t.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function z_(t,e){return iK(e).test(t)}function lK(t,e){if(t!==void 0){let n=t.trim().toLowerCase();if(n==="1"||n==="true"||n==="yes")return!0;if(n==="0"||n==="false"||n==="no")return!1}if(e!==void 0){if(aK.has(e))return!0;if(cK.has(e))return!1}return!1}function J_(t){return t===void 0||t.trim()===""?[]:t.split(",").map(e=>e.trim().toLowerCase()).filter(e=>e.length>0)}function dK(t){if(t===void 0||t==="")return"auto";if(t==="playwright"||t==="agent-browser"||t==="auto")return t;throw new Error(`AFK_BROWSER_BACKEND: must be "playwright", "agent-browser", or "auto", got: ${t}`)}function V_(t){let e=t===void 0||t.trim()===""?"default":t.trim();return bp(e),e}function uK(t){if(t===void 0)return!1;let e=t.trim().toLowerCase();return e==="1"||e==="true"||e==="yes"}function pK(t){try{return oK(t,"utf8")}catch(e){if(e.code==="ENOENT")return;throw e}}function fK(t,e){let n={...t};if(typeof e.headless=="boolean"&&(n.headless=e.headless),Array.isArray(e.allowedDomains)&&(n.allowedDomains=e.allowedDomains.filter(r=>typeof r=="string").map(r=>r.trim().toLowerCase()).filter(r=>r.length>0)),Array.isArray(e.blockedDomains)&&(n.blockedDomains=e.blockedDomains.filter(r=>typeof r=="string").map(r=>r.trim().toLowerCase()).filter(r=>r.length>0)),typeof e.domSnapshots=="boolean"&&(n.domSnapshots=e.domSnapshots),e.backend==="playwright"||e.backend==="agent-browser"||e.backend==="auto")n.backend=e.backend;else if(e.backend!==void 0)throw new Error(`AFK_BROWSER_BACKEND: must be "playwright", "agent-browser", or "auto", got: ${String(e.backend)}`);return typeof e.defaultProfile=="string"&&(n.defaultProfile=V_(e.defaultProfile)),n}function gm(t){let e=t?.env??w,n=t?.readFileSync??pK,r=t?.surface??e.AGENT_SURFACE,o=lK(e.AFK_BROWSER_HEADLESS,r),s=J_(e.AFK_BROWSER_ALLOWED_DOMAINS),i=J_(e.AFK_BROWSER_BLOCKED_DOMAINS),a=uK(e.AFK_BROWSER_DOM_SNAPSHOTS),c=dK(e.AFK_BROWSER_BACKEND),l=V_(e.AFK_BROWSER_DEFAULT_PROFILE),d={headless:o,allowedDomains:s,blockedDomains:i,domSnapshots:a,backend:c,configPath:null,defaultProfile:l},u=e.AFK_BROWSER_CONFIG,p=u!==void 0&&u.trim()!==""?u.trim():sK(Yo(),"browser.json"),f=n(p);if(f===void 0)return d;let g;try{g=JSON.parse(f)}catch(y){throw new Error(`Failed to parse browser config at ${p}: ${String(y)}`)}if(typeof g!="object"||g===null||Array.isArray(g))throw new Error(`Browser config at ${p} must be a JSON object`);let h=fK(d,g);return h.configPath=p,h}function ft(t,e){let n;try{n=new URL(t).hostname.toLowerCase()}catch{return{allowed:!1,reason:`invalid URL: ${t}`}}for(let r of e.blockedDomains)if(z_(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return e.allowedDomains.length>0&&!e.allowedDomains.some(o=>z_(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var aK,cK,cn=m(()=>{"use strict";P();M();aK=new Set(["daemon","subagent","telegram","afk"]),cK=new Set(["repl","interactive","cli"])});import{readFileSync as mK}from"node:fs";import{join as gK}from"node:path";import{homedir as hK}from"node:os";function bK(t){let e=t??yK,n;try{n=mK(e,"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 s;try{s=new URL(o.url)}catch{return null}let{hostname:i,protocol:a}=s;if(!(i==="127.0.0.1"||i==="localhost"||i==="::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 wK(t){try{return process.kill(t,0),!0}catch{return!1}}async function SK(t,e,n=2e3){try{let r=new AbortController,o=setTimeout(()=>r.abort(),n),s=await fetch(`${t}/health`,{method:"GET",headers:{Authorization:`Bearer ${e}`,Host:"127.0.0.1:8833"},signal:r.signal});return clearTimeout(o),s.ok}catch{return!1}}async function ym(t){let e=bK(t);return e===null?{available:!1,connection:null,reason:"connection file missing or invalid"}:wK(e.pid)?await SK(e.url,e.token)?{available:!0,connection:e,reason:null}:{available:!1,connection:e,reason:`health probe failed at ${e.url}`}:{available:!1,connection:e,reason:`stale connection file: PID ${e.pid} not alive`}}var yK,Y_=m(()=>{"use strict";yK=gK(hK(),".config","agent-browser","connection.json")});async function Q_(t){let{config:e,surface:n}=t;if(e.backend==="playwright")return{backend:"playwright",reason:"explicit config: backend=playwright",probeMs:0,availability:null};if(e.backend==="agent-browser"){let i=Date.now(),a=await ym(),c=Date.now()-i;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:c,availability:a}}if(n&&kK.has(n))return{backend:"playwright",reason:`auto: surface "${n}" excluded from Agent Browser`,probeMs:0,availability:null};if(e.headless)return{backend:"playwright",reason:"auto: headless mode requires Playwright",probeMs:0,availability:null};let r=Date.now(),o=await ym(),s=Date.now()-r;return o.available?{backend:"agent-browser",reason:"auto: Agent Browser available and preferred",probeMs:s,availability:o}:{backend:"playwright",reason:`auto: Agent Browser unavailable (${o.reason})`,probeMs:s,availability:o}}var kK,Z_=m(()=>{"use strict";Y_();kK=new Set(["daemon","subagent"])});import{createHash as vK}from"crypto";function eT(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&_K.test(t.label))}function tT(t){return vK("sha256").update(t,"utf8").digest("hex").slice(0,8)}function nT(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var _K,Wc=m(()=>{"use strict";_K=/password|secret|token|api[_-]?key|otp|2fa/i});import{randomBytes as TK}from"crypto";import{mkdir as EK,stat as AK,writeFile as xK}from"fs/promises";import{join as bm}from"path";import{gzip as RK}from"zlib";import{promisify as IK}from"util";function CK(t){return bm(gt(t),"browser")}function PK(t){return bm(CK(t),"screenshots")}function MK(){return new Date().toISOString().replace(/[:.]/g,"-")}function OK(){return TK(3).toString("hex")}async function Xr(t,e,n){if(e.length>rT)throw new Error(`writeScreenshotSidecar: buffer exceeds ${rT} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=PK(t);await EK(r,{recursive:!0});let o=`${MK()}-${OK()}-${n}.png`,s=bm(r,o);await xK(s,e);let{size:i}=await AK(s);return{path:s,bytes:i}}var fie,rT,wm=m(()=>{"use strict";M();Wc();fie=IK(RK);rT=5*1024*1024});var Kc,oT=m(()=>{"use strict";Q();Kc=class{baseUrl;token;constructor(e){this.baseUrl=e.url,this.token=e.token}async call(e,n,r=3e4){let o={version:1,method:e,params:n},s=new AbortController,i=setTimeout(()=>s.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:s.signal});if(!a.ok){let l=await a.text().catch(()=>"");throw new Error(`Agent Browser ${e} failed (HTTP ${a.status}): ${l}`)}let c=await a.json();if(c.ok===!1){let l=c.error,d=l?.code??"UNKNOWN",u=l?.message??JSON.stringify(c);throw new Error(`Agent Browser ${e} failed: [${String(d)}] ${String(u)}`)}return c.result}finally{clearTimeout(i)}}async listTabs(){return this.call("tabs.list",null)}async openTab(e){return{tabId:(await this.call("tabs.open",{url:e},6e4)).id}}async closeTab(e){await this.call("page.eval",{id:e,script:"window.close()"}).catch(n=>{D("[browser/agent-browser] closeTab window.close() failed (tab leak expected)",{tabId:e,err:n})})}async read(e,n){return this.call("page.read",{id:e,mode:n?.mode??"main",...n?.query?{query:n.query}:{},...n?.budget?{budget:n.budget}:{}})}async inspect(e,n){return this.call("page.inspect",{id:e,mode:n?.mode??"interactive",...n?.query?{query:n.query}:{},...n?.limit?{limit:n.limit}:{}})}async click(e,n){await this.call("page.click",{id:e,elementId:n})}async fill(e,n,r){await this.call("page.fill",{id:e,elementId:n,value:r})}async press(e,n,r){await this.call("page.press",{id:e,key:n,...r?{elementId:r}:{}})}async select(e,n,r){await this.call("page.select",{id:e,elementId:n,value:r})}async waitFor(e,n,r){await this.call("page.wait",{id:e,condition:n,...r?.value?{value:r.value}:{},...r?.timeout?{timeout:r.timeout}:{}},(r?.timeout??3e4)+5e3)}async evalScript(e,n){return this.call("page.eval",{id:e,script:n})}async screenshot(e){return this.call("page.screenshot",{id:e})}}});function Sm(t){return{id:t.id,role:t.role,label:t.label,kind:t.kind,value:t.value,state:{disabled:t.disabled,...t.checked!==void 0?{checked:t.checked}:{},...t.selected!==void 0?{selected:t.selected}:{},...t.expanded!==void 0?{expanded:t.expanded}:{}},bbox:t.bbox,...t.selector?{selector:t.selector}:{}}}function sT(t,e){switch(e.kind){case"element_id":if(t.has(e.elementId))return e.elementId;throw new Error(`Element ${e.elementId} not found in current observation. Call browser_observe to refresh.`);case"selector":return null;case"semantic":return null}}async function km(t,e,n,r,o,s){switch(n){case"click":await t.click(e,r);break;case"fill":if(o===void 0)throw new Error("fill requires a value");await t.fill(e,r,o);break;case"press":if(o===void 0)throw new Error("press requires a value (key combo)");await t.press(e,o,r);break;case"select":if(o===void 0)throw new Error("select requires a value");await t.select(e,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 i=r.replace(/\\/g,"\\\\").replace(/"/g,'\\"');await t.evalScript(e,`document.querySelector('[data-element-id="${i}"]')?.scrollIntoView({behavior:'smooth',block:'center'})`);break}case"wait_for":await t.waitFor(e,"element",{value:r,timeout:s??1e4});break;default:throw new Error(`Unknown action: ${n}`)}}async function iT(t,e){if(e.target.kind!=="semantic")throw new Error("resolveSemanticAndAct called with non-semantic target");let{elements:n}=await t.client.inspect(t.tabId,{mode:"interactive",query:e.target.text,limit:10}),r=n;if(e.target.role){let c=e.target.role.toLowerCase();r=n.filter(l=>l.role.toLowerCase()===c)}if(r.length===0)throw new Error(`No element found matching semantic target: text="${e.target.text}"`+(e.target.role?`, role="${e.target.role}"`:""));if(r.length>1)return{outcome:"ambiguous_target",query:{text:e.target.text,...e.target.role?{role:e.target.role}:{}},candidates:r.slice(0,5).map(Sm)};let s=r[0].id;await km(t.client,t.tabId,e.action,s,e.value,e.timeoutMs);let i=await t.client.read(t.tabId,{mode:"main"}),a=ft(i.url,t.config);return a.allowed?{elementId:s}:{outcome:"blocked_by_policy",url:i.url,reason:`action navigated to blocked domain: ${a.reason}`}}var aT=m(()=>{"use strict";cn()});var cT={};qo(cT,{AgentBrowserProvider:()=>vm});var vm,lT=m(()=>{"use strict";cn();wm();oT();aT();vm=class{name="agent-browser";config;client;sessions=new Map;constructor(e,n){this.config=e,this.client=new Kc(n)}async open(e){let n=ft(e.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:e.url,reason:n.reason};let r=this.sessions.get(e.sessionId);if(r)await this.client.evalScript(r.tabId,`window.location.href = ${JSON.stringify(e.url)}`),await this.client.waitFor(r.tabId,"load",{timeout:e.timeoutMs??3e4});else{let{tabId:i}=await this.client.openTab(e.url);await this.client.waitFor(i,"load",{timeout:e.timeoutMs??3e4}),r={tabId:i,observationCounter:0,knownElements:new Map,lastAction:null,lastActionAt:null,currentUrl:null,currentTitle:null},this.sessions.set(e.sessionId,r)}let o=await this.client.read(r.tabId,{mode:"main"}),s=ft(o.url,this.config);return s.allowed?this.buildObservation(r,e.sessionId,e.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: ${s.reason}`})}async observe(e){let n=this.sessions.get(e.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${e.sessionId}. Call browser_open first.`);return this.buildObservation(n,e.sessionId,e.screenshot,e.maxElements,"browser_observe")}async act(e){let n=this.sessions.get(e.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${e.sessionId}. Call browser_open first.`);let r=sT(n.knownElements,e.target);if(r===null){if(e.target.kind==="semantic"){let i=await iT({client:this.client,config:this.config,tabId:n.tabId},e);return"outcome"in i?i:(n.lastAction=`browser_act:${e.action}`,n.lastActionAt=new Date().toISOString(),this.buildObservation(n,e.sessionId,e.screenshot,void 0,"browser_act"))}throw e.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(e.target)}`)}await km(this.client,n.tabId,e.action,r,e.value,e.timeoutMs),n.lastAction=`browser_act:${e.action}`,n.lastActionAt=new Date().toISOString();let o=await this.client.read(n.tabId,{mode:"main"}),s=ft(o.url,this.config);return s.allowed?this.buildObservation(n,e.sessionId,e.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: ${s.reason}`})}async render(e){throw new Error("AgentBrowserProvider does not support render(). Use PlaywrightProvider for one-shot content fetches.")}async screenshot(e){let n=this.sessions.get(e.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${e.sessionId}. Call browser_open first.`);if(e.target!==void 0||e.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"),s=o.length>=24?o.readUInt32BE(16):0,i=o.length>=24?o.readUInt32BE(20):0;return{path:(await Xr(e.sessionId,o,"browser_screenshot")).path,bytes:o.length,width:s,height:i,dataBase64:r.data,mediaType:"image/png"}}async extract(e){throw new Error("AgentBrowserProvider does not support extract() yet.")}async close(e){let n=this.sessions.get(e.sessionId);if(n){try{await this.client.closeTab(n.tabId)}catch{}this.sessions.delete(e.sessionId)}}describe(e){let n=this.sessions.get(e);return n?{active:!0,url:n.currentUrl,title:n.currentTitle,lastAction:n.lastAction,lastActionAt:n.lastActionAt,openTabs:1}:null}async shutdown(){let e=Array.from(this.sessions.entries()).map(async([,n])=>{try{await this.client.closeTab(n.tabId)}catch{}});await Promise.all(e),this.sessions.clear()}async buildObservation(e,n,r,o,s="browser_open"){let[i,a]=await Promise.all([this.client.read(e.tabId,{mode:"main",budget:4e3}),this.client.inspect(e.tabId,{mode:"interactive",limit:o??80})]),c=a.elements.map(Sm),l=o??80,d=c.slice(0,l);e.observationCounter+=1,e.knownElements=new Map(d.map(h=>[h.id,h])),e.currentUrl=i.url,e.currentTitle=i.title;let u=[];c.length>l&&u.push(`page has ${c.length} interactive elements; showing first ${l}`);let p=null;if(r)try{let h=await this.client.screenshot(e.tabId),y=Buffer.from(h.data,"base64");p=(await Xr(n,y,s)).path}catch{u.push("screenshot capture failed")}let f=`obs_${e.observationCounter.toString(36)}`,g={httpStatus:null,loadingState:"idle",hasDialog:!1,consoleErrors:0};return{observationId:f,url:i.url,title:i.title,textSummary:i.content.slice(0,4e3),interactive:d,status:g,warnings:u,screenshotPath:p,capturedAt:new Date().toISOString()}}}});import{existsSync as DK,readFileSync as FK}from"node:fs";import{createRequire as LK}from"node:module";import{dirname as NK,join as UK}from"node:path";function pT(t){if(typeof t=="string")return t;let e=[],n=t;for(let r=0;r<BK&&n instanceof Error;r++)e.push(n.message),n=n.cause;return e.length>0?e.join(" | "):String(t)}function Ue(t){let e=pT(t);return uT.some(n=>e.includes(n))}function jK(){try{let e=LK(import.meta.url).resolve("playwright/package.json"),n=JSON.parse(FK(e,"utf8"));if(typeof n!="object"||n===null)return;let r=n.bin,o=typeof r=="string"?r:typeof r=="object"&&r!==null?r.playwright:void 0;if(typeof o!="string"||o.length===0)return;let s=UK(NK(e),o);return DK(s)?`node ${/\s/.test(s)?`"${s}"`:s} install chromium`:void 0}catch{return}}function Ks(){return dT??=jK()??$K,dT}function _m(t){return t.includes("install chromium")}function nt(t,e){let n=pT(t),r=e?.latched===!0?` ${HK}`:"";if(n.includes("Executable doesn't exist")){let o="";return e?.headless===!0?o=" This launch was headless, which needs the `chromium_headless_shell-*` build.":e?.headless===!1&&(o=" This launch was headed, which needs the full `chromium-*` build \u2014 the headless shell alone does not satisfy it."),`browser tools require the Playwright chromium binary. Install via: ${Ks()}.${o}${r}`}return`browser tools require the optional \`playwright\` peer dependency. Install via: pnpm add playwright (then ${Ks()}). Or pick a different tool.${r}`}function Gc(t,e,n=!1){if(!Ue(t))return t;let r=t instanceof Error?t.message:String(t);return new Error(`${r}
|
|
282
282
|
|
|
283
|
-
${nt(t,{headless:e,latched:n})}`,{cause:t})}var uT,$K,BK,dT,HK,Tm=m(()=>{"use strict";uT=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],$K="pnpm exec playwright install chromium",BK=4;HK="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 Yn from"node:fs";import qc from"node:path";import{randomBytes as WK}from"node:crypto";function KK(){try{return"5.216.1"}catch{}try{let t=qc.resolve(import.meta.dirname,"../../../package.json"),e=Yn.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var GK,Xc,fT=m(()=>{"use strict";Tm();M();Q();GK=KK(),Xc=class{config;browser;sessions=new Map;launchPromise;launchFailure;shutdownComplete=!1;constructor(e){this.config=e}clearLaunchFailure(){this.launchFailure=void 0}latchLaunchFailure(e){this.launchFailure={error:e}}async ensureBrowser(){if(this.browser!==void 0&&this.browser.isConnected())return this.browser;if(this.launchFailure!==void 0)throw this.launchFailure.error;return this.browser!==void 0&&!this.browser.isConnected()&&(this.browser=void 0,this.launchPromise=void 0),this.launchPromise!==void 0?this.launchPromise:(this.launchPromise=(async()=>{let e;try{({chromium:e}=await import("playwright"))}catch(n){let r=Gc(n,this.config.headless,!0);throw this.latchLaunchFailure(r),this.launchPromise=void 0,r}try{let n=await e.launch({headless:this.config.headless});return this.browser=n,this.clearLaunchFailure(),n}catch(n){let r=Gc(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(e){let n=this.sessions.get(e);if(n!==void 0)return n.context;let r=await this.ensureBrowser(),o=this.loadStorageState(this.config.defaultProfile),s=await r.newContext({...this.contextOptions(),...o!==void 0?{storageState:o}:{}}),i={context:s,page:void 0,consoleErrors:0,lastHttpStatus:null,openDialog:void 0};return this.sessions.set(e,i),s}async ensurePage(e){let n=this.sessions.get(e);if(n!==void 0&&n.page!==void 0)return n.page;await this.ensureContext(e);let r=this.sessions.get(e);if(r===void 0)throw new Error(`[BrowserLauncher] session entry disappeared for sessionId=${e}`);if(r.page!==void 0)return r.page;let o=await r.context.newPage();return r.page=o,o.on("console",s=>{s.type()==="error"&&(r.consoleErrors+=1)}),o.on("request",s=>{s.isNavigationRequest()&&s.frame()===o.mainFrame()&&(r.lastHttpStatus=null)}),o.on("response",s=>{s.frame()===o.mainFrame()&&s.request().isNavigationRequest()&&(r.lastHttpStatus=s.status())}),o.on("dialog",s=>{r.openDialog=s}),o}getPage(e){return this.sessions.get(e)?.page}async renderHtml(e,n){let o=await(await this.ensureBrowser()).newContext(this.contextOptions()),s;n.requestGuard!==void 0&&await o.route("**/*",async a=>{try{await n.requestGuard(a.request().url()),await a.continue()}catch(c){s=c,await a.abort("blockedbyclient")}});let i=()=>{o.close().catch(()=>{})};if(n.signal?.aborted===!0)throw await o.close().catch(()=>{}),new Error("render aborted");n.signal!==void 0&&n.signal.addEventListener("abort",i,{once:!0});try{let a=await o.newPage(),c;try{c=await a.goto(e,{timeout:n.timeoutMs,waitUntil:n.waitUntil})}catch(p){throw s??p}if(s!==void 0)throw s;let l=await a.content();if(s!==void 0)throw s;let d=a.url(),u=c!==null?c.status():null;return{html:l,finalUrl:d,httpStatus:u}}finally{n.signal!==void 0&&n.signal.removeEventListener("abort",i),await o.close().catch(()=>{})}}getConsoleErrorCount(e){return this.sessions.get(e)?.consoleErrors??0}getLastHttpStatus(e){return this.sessions.get(e)?.lastHttpStatus??null}hasOpenDialog(e){return this.sessions.get(e)?.openDialog!==void 0}async dismissDialog(e,n=!0){let r=this.sessions.get(e);if(r===void 0||r.openDialog===void 0)return;let o=r.openDialog;r.openDialog=void 0,n?await o.accept():await o.dismiss()}async closeSession(e){this.clearLaunchFailure();let n=this.sessions.get(e);n!==void 0&&(this.sessions.delete(e),await this.saveStorageState(this.config.defaultProfile,n.context),n.page!==void 0&&await n.page.close().catch(()=>{}),await n.context.close().catch(()=>{}))}async shutdown(){if(this.clearLaunchFailure(),this.shutdownComplete)return;this.shutdownComplete=!0;let e=[...this.sessions.keys()];if(await Promise.all(e.map(n=>this.closeSession(n))),this.browser!==void 0){let n=this.browser;this.browser=void 0,await n.close().catch(()=>{})}}activeSessions(){return this.sessions.size}contextOptions(){return{viewport:{width:1280,height:800},userAgent:`Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 agent-afk/${GK}`}}loadStorageState(e){let n=wp(e);try{if(!Yn.existsSync(n))return;let r=JSON.parse(Yn.readFileSync(n,"utf8"));return D("[browser/vault] restored session",{profile:e,file:n}),r}catch(r){D("[browser/vault] ignoring unreadable vault",{profile:e,file:n,err:r});return}}async saveStorageState(e,n){try{let r=wp(e);if(!Yn.existsSync(r))return;let o=await n.storageState(),s=qc.join(qc.dirname(r),`.${qc.basename(r)}.${process.pid}.${WK(4).toString("hex")}.tmp`);Yn.writeFileSync(s,JSON.stringify(o),{mode:384}),Yn.chmodSync(s,384),Yn.renameSync(s,r),D("[browser/vault] saved session",{profile:e,file:r})}catch(r){D("[browser/vault] save failed",{profile:e,err:r})}}}});import{createHash as qK}from"node:crypto";function XK(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function zK(t,e,n){return`el_${qK("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function JK(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function mT(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function hT(t,e){let n=t.role??"",r=t.name??"";gT.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])hT(s,e)}async function VK(t){return t.evaluate(e=>{let n=Array.from(document.querySelectorAll(e)),r=[];for(let o of n){let s=o.getBoundingClientRect(),i=o;if(s.width===0&&s.height===0){let d=window.getComputedStyle(i);if(d.display==="none"||d.visibility==="hidden")continue}let a=o.tagName.toLowerCase(),c=o.getAttribute("aria-label")??o.getAttribute("placeholder")??(o.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a==="input"?o.type||null:o.getAttribute("type");r.push({name:c,tagName:a,type:l,id:o.id||null,testId:o.getAttribute("data-testid"),bbox:{x:Math.round(s.left),y:Math.round(s.top),w:Math.round(s.width),h:Math.round(s.height)}})}return r},yT).catch(()=>[])}async function YK(t){return t.evaluate(e=>{let n={button:"button",a:"link",input:"textbox",textarea:"textbox",select:"combobox"},r=Array.from(document.querySelectorAll(e)),o=[];for(let s of r){let i=s.tagName.toLowerCase(),a=s.getAttribute("role")??"",c=s.getAttribute("aria-label")??s.getAttribute("placeholder")??(s.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a||(n[i]??"");if(i==="input"){let h=s.type;h==="checkbox"?l="checkbox":h==="radio"?l="radio":h==="button"||h==="submit"||h==="reset"?l="button":h==="search"?l="searchbox":l="textbox"}if(!l)continue;let d="value"in s?s.value:void 0,u=d!==void 0?String(d):void 0,p=s.disabled??!1,f=i==="input"?s.checked:void 0,g={role:l,name:c,disabled:p};u!==void 0&&(g.value=u),f!==void 0&&(g.checked=f),o.push(g)}return o},yT).catch(()=>[])}function QK(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function zc(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=QK(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=VK(t),c=t.evaluate(()=>document.body?.innerText??"").catch(()=>""),l=Promise.resolve(t.url()),d=t.title().catch(()=>""),[u,p,f,g,h]=await Promise.all([i,a,c,l,d]),y,b=!1;u!==null?(y=[],hT(u,y)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,y=(await YK(t)).filter(C=>gT.has(C.role??"")));let S=new Map;for(let T of p){let C=mT(T.name),N=S.get(C);(!N||N.bbox.w===0&&T.bbox.w>0)&&S.set(C,T)}let k=y.map(T=>({ax:T,dom:S.get(mT(T.name??""))})),_=r?k:k.filter(T=>T.dom?T.dom.bbox.w>0||T.dom.bbox.h>0:!0);_.sort((T,C)=>{let N=T.dom?.bbox.y??0,O=C.dom?.bbox.y??0;if(N!==O)return N-O;let U=T.dom?.bbox.x??0,L=C.dom?.bbox.x??0;return U-L}),_.length>200&&o.push("page has 200+ interactive elements; consider scoping");let R=_.slice(0,n).map((T,C)=>{let N=T.ax.role??"generic",O=T.ax.name??"",U=zK(N,O,C),L=T.dom?.bbox??{x:0,y:0,w:0,h:0},$=T.dom?.type??null,q=null;T.ax.value!==void 0&&T.ax.value!==null&&(q=String(T.ax.value)),T.ax.checked!==void 0&&(q=String(T.ax.checked)),eT({role:N,kind:$})&&(q="[redacted]");let K={disabled:T.ax.disabled??!1};T.ax.checked!==void 0&&(K.checked=T.ax.checked===!0||T.ax.checked==="mixed"),T.ax.selected!==void 0&&(K.selected=T.ax.selected),T.ax.expanded!==void 0&&(K.expanded=T.ax.expanded);let ne;T.dom?.testId?ne=`[data-testid="${T.dom.testId}"]`:T.dom?.id&&(ne=`#${T.dom.id}`);let Rn={id:U,role:N,label:XK(O),kind:$,value:q,state:K,bbox:L};return ne!==void 0&&(Rn.selector=ne),Rn}),A="idle";try{let T=await t.evaluate(()=>document.readyState);T==="loading"?A="loading":T==="interactive"?A="navigating":A="idle"}catch{A="navigating"}A!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),b&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let F=JK(f),v=`obs_${e.observationCounter.toString(36)}`,x=new Date().toISOString();return{observationId:v,url:g,title:h,textSummary:F,interactive:R,status:{httpStatus:e.httpStatus??null,loadingState:A,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:x}}var gT,yT,bT=m(()=>{"use strict";Wc();gT=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);yT="a[href], button, input, select, textarea, [role], [tabindex], label"});async function wT(t,e){try{let n=await t.nth(e).evaluate(i=>{let a=i,c=a.getAttribute("role")??a.tagName.toLowerCase(),l=a.getAttribute("aria-label")??a.getAttribute("placeholder")??(a.innerText!=null?a.innerText.trim().slice(0,200):"")??a.getAttribute("title")??"",d=a.getBoundingClientRect();return{role:c,label:l,x:Math.round(d.x),y:Math.round(d.y),w:Math.round(d.width),h:Math.round(d.height)}}),r=`${n.role}:${n.label}:${e}`,o=0;for(let i=0;i<r.length;i++)o=o*31+r.charCodeAt(i)>>>0;return{id:`el_${o.toString(16).padStart(6,"0").slice(0,6)}`,role:n.role,label:n.label,kind:null,value:null,state:{disabled:!1},bbox:{x:n.x,y:n.y,w:n.w,h:n.h}}}catch{return null}}async function Em(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>wT(t,s)))).filter(o=>o!==null)}async function ZK(t){let e=new Set,n=[];for(let{loc:r,count:o}of t)for(let s=0;s<o;s++){let i;try{i=await r.nth(s).evaluate(a=>{let c=a,l=c.getBoundingClientRect();return`${c.tagName}@${Math.round(l.x)},${Math.round(l.y)}`})}catch{continue}e.has(i)||(e.add(i),n.push({key:i,locator:r,index:s}))}return n}async function Am(t,e,n){switch(e.kind){case"element_id":return eG(t,e,n);case"selector":return tG(t,e);case"semantic":return nG(t,e)}}async function eG(t,e,n){let r=n.get(e.elementId);if(r===void 0)return{outcome:"not_found",query:e};if(r.selector!==void 0){let c=t.locator(r.selector);if(await c.count()===1)return{outcome:"resolved",locator:c}}let o=t.getByRole(r.role,{name:r.label,exact:!0}),s=await o.count();if(s===0)return{outcome:"not_found",query:e};if(s===1)return{outcome:"resolved",locator:o};let i=await Em(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function tG(t,e){let n=t.locator(e.selector),r=await n.count();if(r===0)return{outcome:"not_found",query:e};if(r===1)return{outcome:"resolved",locator:n};let o=await Em(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function nG(t,e){return e.role!==void 0?rG(t,e.text,e.role):oG(t,e.text,e)}async function rG(t,e,n){let r=t.getByRole(n,{name:e}),o=await r.count();if(o===0)return{outcome:"not_found",query:{kind:"semantic",text:e,role:n}};if(o===1)return{outcome:"resolved",locator:r};let s=await Em(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function oG(t,e,n){let r=t.getByRole("button",{name:e}),o=t.getByRole("link",{name:e}),s=t.getByLabel(e,{exact:!1}),[i,a,c]=await Promise.all([r.count(),o.count(),s.count()]);if(i+a+c===0)return{outcome:"not_found",query:n};let d=[];i>0&&d.push({loc:r,count:i}),a>0&&d.push({loc:o,count:a}),c>0&&d.push({loc:s,count:c});let u=await ZK(d);if(u.length===0)return{outcome:"not_found",query:n};if(u.length===1){let h=u[0];return h===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:h.locator.nth(h.index)}}let p=u.slice(0,5),f=[];for(let h=0;h<p.length;h++){let y=p[h];if(y===void 0)continue;let b=await wT(y.locator,y.index);if(b!==null){let S=`${b.role}:${b.label}:${h}`,k=0;for(let _=0;_<S.length;_++)k=k*31+S.charCodeAt(_)>>>0;f.push({...b,id:`el_${k.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var ST=m(()=>{"use strict"});async function xm(t,e,n,r){let o=t.url();if(o===n)return null;let s=ft(o,e);if(s.allowed)return null;try{await t.goBack()}catch{await r()}return{outcome:"blocked_by_policy",url:o,reason:s.reason}}var kT=m(()=>{"use strict";cn()});var Im={};qo(Im,{PlaywrightProvider:()=>Rm});function vT(t){switch(t.kind){case"semantic":return t.role!==void 0?`semantic('${t.text}', role='${t.role}')`:`semantic('${t.text}')`;case"element_id":return`element_id(${t.elementId})`;case"selector":return`selector(${t.selector})`}}var Rm,Cm=m(()=>{"use strict";fT();bT();ST();cn();kT();wm();Rm=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new Xc(e)}async open(e){let n=ft(e.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:e.url,reason:n.reason};let{sessionId:r}=e,o=await this.launcher.ensurePage(r),s=this.ensureSessionState(r),i=null,a=null;try{await o.goto(e.url,{timeout:e.timeoutMs??3e4,waitUntil:e.waitFor??"load"})}catch(u){a=u}let c=o.url();if(!(a!==null&&(c===""||c==="about:blank"))){let u=await xm(o,this.config,e.url,()=>this.close({sessionId:r}));if(u!==null)return u}(e.screenshot===!0||a!==null)&&(i=await this.captureScreenshot(o,r,"browser_open")),s.observationCounter+=1;let d=await zc(o,{observationCounter:s.observationCounter,screenshotPath:i,consoleErrors:this.launcher.getConsoleErrorCount(r),httpStatus:this.launcher.getLastHttpStatus(r),hasDialog:this.launcher.hasOpenDialog(r)});if(this.updateSessionFromObservation(s,d.interactive,d.url,d.title,"browser_open"),a!==null)throw a;return d}async observe(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_observe: no page open for session ${n}`);let o=this.ensureSessionState(n),s=null;e.screenshot===!0&&(s=await this.captureScreenshot(r,n,"browser_observe")),o.observationCounter+=1;let i=await zc(r,{observationCounter:o.observationCounter,screenshotPath:s,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n),includeHidden:e.includeHidden,maxElements:e.maxElements});return this.updateSessionFromObservation(o,i.interactive,i.url,i.title,"browser_observe"),i}async act(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_act: no page open for session ${n}`);let o=this.ensureSessionState(n),s=r.url(),i=e.timeoutMs??3e4,a=await Am(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${vT(e.target)}`);if(a.outcome==="ambiguous_target")return a;let{locator:c}=a,l=null,d=async()=>{switch(e.action){case"click":await c.click({timeout:i});break;case"fill":await c.fill(e.value??"");break;case"press":await c.press(e.value??"");break;case"select":await c.selectOption(e.value??"");break;case"hover":await c.hover({timeout:i});break;case"scroll_to":await c.scrollIntoViewIfNeeded({timeout:i});break;case"wait_for":await c.waitFor({timeout:i,state:"visible"});break}};try{await d()}catch(h){if(h instanceof Error&&/navigation|net::ERR/i.test(h.message))try{await d()}catch(y){l=y}else l=h}let u=await xm(r,this.config,s,()=>this.close({sessionId:n}));if(u!==null)return u;let p=null;(e.screenshot===!0||l!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await zc(r,{observationCounter:o.observationCounter,screenshotPath:p,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),g=`browser_act:${e.action}`;if(this.updateSessionFromObservation(o,f.interactive,f.url,f.title,g),l!==null)throw l;return f}async render(e){return this.launcher.renderHtml(e.url,{timeoutMs:e.timeoutMs??3e4,waitUntil:e.waitFor??"load",signal:e.signal,requestGuard:e.requestGuard})}async screenshot(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_screenshot: no page open for session ${n}`);let o=this.ensureSessionState(n),s;if(e.target!==void 0){let d=await Am(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${vT(e.target)}`);if(d.outcome==="ambiguous_target")throw new Error("screenshot target ambiguous; specify element_id or selector");s=await d.locator.screenshot()}else s=await r.screenshot({fullPage:e.fullPage??!1});let{path:i,bytes:a}=await Xr(n,s,"browser_screenshot"),c=0,l=0;if(e.fullPage===!0)try{let d=await r.evaluate(()=>({w:document.documentElement.scrollWidth,h:document.documentElement.scrollHeight}));c=d.w,l=d.h}catch{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}else{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}return{path:i,bytes:a,width:c,height:l,dataBase64:s.toString("base64"),mediaType:"image/png"}}async extract(e){throw new Error("browser_extract not implemented in Phase 1")}async close(e){await this.launcher.closeSession(e.sessionId),this.sessions.delete(e.sessionId)}describe(e){let n=this.sessions.get(e);if(n===void 0)return null;let r=this.launcher.getPage(e);return{active:r!==void 0,url:n.currentUrl,title:n.currentTitle,lastAction:n.lastAction,lastActionAt:n.lastActionAt,openTabs:r!==void 0?1:0}}async shutdown(){this.sessions.clear(),await this.launcher.shutdown()}ensureSessionState(e){let n=this.sessions.get(e);if(n!==void 0)return n;let r={observationCounter:0,knownElements:new Map,lastAction:null,lastActionAt:null,currentUrl:null,currentTitle:null};return this.sessions.set(e,r),r}updateSessionFromObservation(e,n,r,o,s){e.knownElements=new Map(n.map(i=>[i.id,i])),e.currentUrl=r,e.currentTitle=o,e.lastAction=s,e.lastActionAt=new Date().toISOString()}async captureScreenshot(e,n,r){try{let o=await e.screenshot({fullPage:!1}),{path:s}=await Xr(n,o,r);return s}catch{return null}}}});var Zn={};qo(Zn,{__resetBrowserRegistryForTests:()=>dG,browserProviderActive:()=>aG,closeBrowserProvider:()=>Mm,getBrowserProvider:()=>iG,getLastRoutingDecision:()=>lG,peekBrowserProvider:()=>cG});function _T(){Promise.resolve(Mm()).then(()=>{process.exit(130)})}function TT(){Promise.resolve(Mm()).then(()=>{process.exit(143)})}function ET(){Et=null}function sG(){Jc||(process.on("SIGINT",_T),process.on("SIGTERM",TT),process.on("exit",ET),Jc=!0)}function AT(){Jc&&(process.removeListener("SIGINT",_T),process.removeListener("SIGTERM",TT),process.removeListener("exit",ET),Jc=!1)}async function iG(t){return Et!==null?Et:(Qn!==null||(Qn=(async()=>{let e=gm(t),n=t?.surface??(t?.env??{}).AGENT_SURFACE??w.AGENT_SURFACE,r=await Q_({config:e,surface:n});Pm=r;let o;if(r.backend==="agent-browser"){let{AgentBrowserProvider:s}=await Promise.resolve().then(()=>(lT(),cT)),i=r.availability.connection;o=new s(e,i)}else{let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(Cm(),Im));o=new s(e)}return sG(),Et=o,Qn=null,o})()),Qn)}async function Mm(){if(Et===null)return;let t=Et;Et=null,Qn=null,AT(),await t.shutdown()}function aG(){return Et!==null}function cG(){return Et}function lG(){return Pm}function dG(){Et=null,Qn=null,Pm=null,AT()}var Et,Qn,Jc,Pm,er=m(()=>{"use strict";cn();Z_();P();Et=null,Qn=null,Jc=!1,Pm=null});async function xT(t,e){try{return await $_(t,e)}catch(n){return D("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function hG(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(er(),Zn)),r=await n();try{return await r.render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}catch(o){if(r.name==="agent-browser"){let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(Cm(),Im)),{loadBrowserConfig:i}=await Promise.resolve().then(()=>(cn(),hm)),a=i(),c=new s(a);try{return await c.render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}finally{await c.shutdown()}}throw o}}async function RT(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??hG,o=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},s=null,i="",a=t,c=null,l=null;try{let u=await an(n,t,{headers:gG,signal:e.signal},o);c=u.status,a=u.url||t;let p=u.headers.get("content-type")??"";if(u.ok){if(mG.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 u.text();if(fG.test(p)&&!pG.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await xT(f,a),e.signal.aborted)throw e.signal.reason??new Error("aborted")}}catch(u){if(e.signal.aborted||u instanceof ve||u instanceof Error&&u.message.startsWith("web_scrape markdown mode received binary"))throw u;l=u}if(!(s===null||s.textLength<200)&&s!==null){let u=um({html:i,extractedTextLength:s.textLength});return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1,...u!==void 0?{advisory:u}:{}}}try{await Ws(t,o);let u=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:f=>Ws(f,o)});u.finalUrl!==t&&/^https?:\/\//i.test(u.finalUrl)&&await Ws(u.finalUrl,o);let p=await xT(u.html,u.finalUrl);if(e.signal.aborted)throw e.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=um({html:u.html,extractedTextLength:p.textLength});return{title:p.title,markdown:p.markdown,finalUrl:u.finalUrl,usedRender:!0,...f!==void 0?{advisory:f}:{}}}}catch(u){if(e.signal.aborted||u instanceof ve)throw u;if(s===null){let p=u instanceof Error?u.message:String(u),f=l instanceof Error?l.message:`HTTP ${c??"error"}`,g=new Error(`web_scrape could not retrieve ${t}: fetch failed (${f}) and render failed (${p}).`);throw g.cause=u,g}}if(s!==null)return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1};throw new Error(`web_scrape could not retrieve any content from ${t} (HTTP ${c??"error"}).`)}var pG,fG,mG,gG,IT=m(()=>{"use strict";B_();pm();Vn();Q();pG=/(text\/html|application\/xhtml\+xml)/i,fG=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,mG=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,gG={"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 wG(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(yG,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json","x-api-key":t.apiKey,"User-Agent":"agent-afk/web_scrape"},body:JSON.stringify({query:n,type:"auto",numResults:Math.min(Math.max(r,1),bG),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let c="";try{let d=await s.text(),u=ue(d);u&&(c=`: ${u.length>200?u.slice(0,200)+"\u2026":u}`)}catch{}let l=s.statusText?` ${s.statusText}`:"";throw new Error(`Exa Search HTTP ${s.status}${l}${c}`)}let i;try{i=await s.json()}catch(c){throw new Error(`Exa Search response was not JSON: ${c instanceof Error?c.message:String(c)}`)}return(i.results??[]).slice(0,r).map(c=>({title:(c.title??"").trim()||"(untitled)",url:c.url??"",description:(c.highlights?.[0]??"").trim()})).filter(c=>c.url.length>0)}}}function CT(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?wG({apiKey:t.exaApiKey,fetchFn:t.fetchFn}):{error:'web_scrape search mode requires a search backend. Set EXA_API_KEY (free tier at https://exa.ai) to enable it. Use mode: "markdown" to read a known URL, or mode: "raw" for a direct fetch.'}}function PT(t,e){if(e.length===0)return`# Search results for "${t}"
|
|
283
|
+
${nt(t,{headless:e,latched:n})}`,{cause:t})}var uT,$K,BK,dT,HK,Tm=m(()=>{"use strict";uT=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],$K="pnpm exec playwright install chromium",BK=4;HK="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 Yn from"node:fs";import qc from"node:path";import{randomBytes as WK}from"node:crypto";function KK(){try{return"5.217.0"}catch{}try{let t=qc.resolve(import.meta.dirname,"../../../package.json"),e=Yn.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var GK,Xc,fT=m(()=>{"use strict";Tm();M();Q();GK=KK(),Xc=class{config;browser;sessions=new Map;launchPromise;launchFailure;shutdownComplete=!1;constructor(e){this.config=e}clearLaunchFailure(){this.launchFailure=void 0}latchLaunchFailure(e){this.launchFailure={error:e}}async ensureBrowser(){if(this.browser!==void 0&&this.browser.isConnected())return this.browser;if(this.launchFailure!==void 0)throw this.launchFailure.error;return this.browser!==void 0&&!this.browser.isConnected()&&(this.browser=void 0,this.launchPromise=void 0),this.launchPromise!==void 0?this.launchPromise:(this.launchPromise=(async()=>{let e;try{({chromium:e}=await import("playwright"))}catch(n){let r=Gc(n,this.config.headless,!0);throw this.latchLaunchFailure(r),this.launchPromise=void 0,r}try{let n=await e.launch({headless:this.config.headless});return this.browser=n,this.clearLaunchFailure(),n}catch(n){let r=Gc(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(e){let n=this.sessions.get(e);if(n!==void 0)return n.context;let r=await this.ensureBrowser(),o=this.loadStorageState(this.config.defaultProfile),s=await r.newContext({...this.contextOptions(),...o!==void 0?{storageState:o}:{}}),i={context:s,page:void 0,consoleErrors:0,lastHttpStatus:null,openDialog:void 0};return this.sessions.set(e,i),s}async ensurePage(e){let n=this.sessions.get(e);if(n!==void 0&&n.page!==void 0)return n.page;await this.ensureContext(e);let r=this.sessions.get(e);if(r===void 0)throw new Error(`[BrowserLauncher] session entry disappeared for sessionId=${e}`);if(r.page!==void 0)return r.page;let o=await r.context.newPage();return r.page=o,o.on("console",s=>{s.type()==="error"&&(r.consoleErrors+=1)}),o.on("request",s=>{s.isNavigationRequest()&&s.frame()===o.mainFrame()&&(r.lastHttpStatus=null)}),o.on("response",s=>{s.frame()===o.mainFrame()&&s.request().isNavigationRequest()&&(r.lastHttpStatus=s.status())}),o.on("dialog",s=>{r.openDialog=s}),o}getPage(e){return this.sessions.get(e)?.page}async renderHtml(e,n){let o=await(await this.ensureBrowser()).newContext(this.contextOptions()),s;n.requestGuard!==void 0&&await o.route("**/*",async a=>{try{await n.requestGuard(a.request().url()),await a.continue()}catch(c){s=c,await a.abort("blockedbyclient")}});let i=()=>{o.close().catch(()=>{})};if(n.signal?.aborted===!0)throw await o.close().catch(()=>{}),new Error("render aborted");n.signal!==void 0&&n.signal.addEventListener("abort",i,{once:!0});try{let a=await o.newPage(),c;try{c=await a.goto(e,{timeout:n.timeoutMs,waitUntil:n.waitUntil})}catch(p){throw s??p}if(s!==void 0)throw s;let l=await a.content();if(s!==void 0)throw s;let d=a.url(),u=c!==null?c.status():null;return{html:l,finalUrl:d,httpStatus:u}}finally{n.signal!==void 0&&n.signal.removeEventListener("abort",i),await o.close().catch(()=>{})}}getConsoleErrorCount(e){return this.sessions.get(e)?.consoleErrors??0}getLastHttpStatus(e){return this.sessions.get(e)?.lastHttpStatus??null}hasOpenDialog(e){return this.sessions.get(e)?.openDialog!==void 0}async dismissDialog(e,n=!0){let r=this.sessions.get(e);if(r===void 0||r.openDialog===void 0)return;let o=r.openDialog;r.openDialog=void 0,n?await o.accept():await o.dismiss()}async closeSession(e){this.clearLaunchFailure();let n=this.sessions.get(e);n!==void 0&&(this.sessions.delete(e),await this.saveStorageState(this.config.defaultProfile,n.context),n.page!==void 0&&await n.page.close().catch(()=>{}),await n.context.close().catch(()=>{}))}async shutdown(){if(this.clearLaunchFailure(),this.shutdownComplete)return;this.shutdownComplete=!0;let e=[...this.sessions.keys()];if(await Promise.all(e.map(n=>this.closeSession(n))),this.browser!==void 0){let n=this.browser;this.browser=void 0,await n.close().catch(()=>{})}}activeSessions(){return this.sessions.size}contextOptions(){return{viewport:{width:1280,height:800},userAgent:`Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 agent-afk/${GK}`}}loadStorageState(e){let n=wp(e);try{if(!Yn.existsSync(n))return;let r=JSON.parse(Yn.readFileSync(n,"utf8"));return D("[browser/vault] restored session",{profile:e,file:n}),r}catch(r){D("[browser/vault] ignoring unreadable vault",{profile:e,file:n,err:r});return}}async saveStorageState(e,n){try{let r=wp(e);if(!Yn.existsSync(r))return;let o=await n.storageState(),s=qc.join(qc.dirname(r),`.${qc.basename(r)}.${process.pid}.${WK(4).toString("hex")}.tmp`);Yn.writeFileSync(s,JSON.stringify(o),{mode:384}),Yn.chmodSync(s,384),Yn.renameSync(s,r),D("[browser/vault] saved session",{profile:e,file:r})}catch(r){D("[browser/vault] save failed",{profile:e,err:r})}}}});import{createHash as qK}from"node:crypto";function XK(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function zK(t,e,n){return`el_${qK("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function JK(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function mT(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function hT(t,e){let n=t.role??"",r=t.name??"";gT.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])hT(s,e)}async function VK(t){return t.evaluate(e=>{let n=Array.from(document.querySelectorAll(e)),r=[];for(let o of n){let s=o.getBoundingClientRect(),i=o;if(s.width===0&&s.height===0){let d=window.getComputedStyle(i);if(d.display==="none"||d.visibility==="hidden")continue}let a=o.tagName.toLowerCase(),c=o.getAttribute("aria-label")??o.getAttribute("placeholder")??(o.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a==="input"?o.type||null:o.getAttribute("type");r.push({name:c,tagName:a,type:l,id:o.id||null,testId:o.getAttribute("data-testid"),bbox:{x:Math.round(s.left),y:Math.round(s.top),w:Math.round(s.width),h:Math.round(s.height)}})}return r},yT).catch(()=>[])}async function YK(t){return t.evaluate(e=>{let n={button:"button",a:"link",input:"textbox",textarea:"textbox",select:"combobox"},r=Array.from(document.querySelectorAll(e)),o=[];for(let s of r){let i=s.tagName.toLowerCase(),a=s.getAttribute("role")??"",c=s.getAttribute("aria-label")??s.getAttribute("placeholder")??(s.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a||(n[i]??"");if(i==="input"){let h=s.type;h==="checkbox"?l="checkbox":h==="radio"?l="radio":h==="button"||h==="submit"||h==="reset"?l="button":h==="search"?l="searchbox":l="textbox"}if(!l)continue;let d="value"in s?s.value:void 0,u=d!==void 0?String(d):void 0,p=s.disabled??!1,f=i==="input"?s.checked:void 0,g={role:l,name:c,disabled:p};u!==void 0&&(g.value=u),f!==void 0&&(g.checked=f),o.push(g)}return o},yT).catch(()=>[])}function QK(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function zc(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=QK(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=VK(t),c=t.evaluate(()=>document.body?.innerText??"").catch(()=>""),l=Promise.resolve(t.url()),d=t.title().catch(()=>""),[u,p,f,g,h]=await Promise.all([i,a,c,l,d]),y,b=!1;u!==null?(y=[],hT(u,y)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,y=(await YK(t)).filter(C=>gT.has(C.role??"")));let S=new Map;for(let T of p){let C=mT(T.name),N=S.get(C);(!N||N.bbox.w===0&&T.bbox.w>0)&&S.set(C,T)}let k=y.map(T=>({ax:T,dom:S.get(mT(T.name??""))})),_=r?k:k.filter(T=>T.dom?T.dom.bbox.w>0||T.dom.bbox.h>0:!0);_.sort((T,C)=>{let N=T.dom?.bbox.y??0,O=C.dom?.bbox.y??0;if(N!==O)return N-O;let U=T.dom?.bbox.x??0,L=C.dom?.bbox.x??0;return U-L}),_.length>200&&o.push("page has 200+ interactive elements; consider scoping");let R=_.slice(0,n).map((T,C)=>{let N=T.ax.role??"generic",O=T.ax.name??"",U=zK(N,O,C),L=T.dom?.bbox??{x:0,y:0,w:0,h:0},$=T.dom?.type??null,q=null;T.ax.value!==void 0&&T.ax.value!==null&&(q=String(T.ax.value)),T.ax.checked!==void 0&&(q=String(T.ax.checked)),eT({role:N,kind:$})&&(q="[redacted]");let K={disabled:T.ax.disabled??!1};T.ax.checked!==void 0&&(K.checked=T.ax.checked===!0||T.ax.checked==="mixed"),T.ax.selected!==void 0&&(K.selected=T.ax.selected),T.ax.expanded!==void 0&&(K.expanded=T.ax.expanded);let ne;T.dom?.testId?ne=`[data-testid="${T.dom.testId}"]`:T.dom?.id&&(ne=`#${T.dom.id}`);let Rn={id:U,role:N,label:XK(O),kind:$,value:q,state:K,bbox:L};return ne!==void 0&&(Rn.selector=ne),Rn}),A="idle";try{let T=await t.evaluate(()=>document.readyState);T==="loading"?A="loading":T==="interactive"?A="navigating":A="idle"}catch{A="navigating"}A!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),b&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let F=JK(f),v=`obs_${e.observationCounter.toString(36)}`,x=new Date().toISOString();return{observationId:v,url:g,title:h,textSummary:F,interactive:R,status:{httpStatus:e.httpStatus??null,loadingState:A,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:x}}var gT,yT,bT=m(()=>{"use strict";Wc();gT=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);yT="a[href], button, input, select, textarea, [role], [tabindex], label"});async function wT(t,e){try{let n=await t.nth(e).evaluate(i=>{let a=i,c=a.getAttribute("role")??a.tagName.toLowerCase(),l=a.getAttribute("aria-label")??a.getAttribute("placeholder")??(a.innerText!=null?a.innerText.trim().slice(0,200):"")??a.getAttribute("title")??"",d=a.getBoundingClientRect();return{role:c,label:l,x:Math.round(d.x),y:Math.round(d.y),w:Math.round(d.width),h:Math.round(d.height)}}),r=`${n.role}:${n.label}:${e}`,o=0;for(let i=0;i<r.length;i++)o=o*31+r.charCodeAt(i)>>>0;return{id:`el_${o.toString(16).padStart(6,"0").slice(0,6)}`,role:n.role,label:n.label,kind:null,value:null,state:{disabled:!1},bbox:{x:n.x,y:n.y,w:n.w,h:n.h}}}catch{return null}}async function Em(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>wT(t,s)))).filter(o=>o!==null)}async function ZK(t){let e=new Set,n=[];for(let{loc:r,count:o}of t)for(let s=0;s<o;s++){let i;try{i=await r.nth(s).evaluate(a=>{let c=a,l=c.getBoundingClientRect();return`${c.tagName}@${Math.round(l.x)},${Math.round(l.y)}`})}catch{continue}e.has(i)||(e.add(i),n.push({key:i,locator:r,index:s}))}return n}async function Am(t,e,n){switch(e.kind){case"element_id":return eG(t,e,n);case"selector":return tG(t,e);case"semantic":return nG(t,e)}}async function eG(t,e,n){let r=n.get(e.elementId);if(r===void 0)return{outcome:"not_found",query:e};if(r.selector!==void 0){let c=t.locator(r.selector);if(await c.count()===1)return{outcome:"resolved",locator:c}}let o=t.getByRole(r.role,{name:r.label,exact:!0}),s=await o.count();if(s===0)return{outcome:"not_found",query:e};if(s===1)return{outcome:"resolved",locator:o};let i=await Em(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function tG(t,e){let n=t.locator(e.selector),r=await n.count();if(r===0)return{outcome:"not_found",query:e};if(r===1)return{outcome:"resolved",locator:n};let o=await Em(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function nG(t,e){return e.role!==void 0?rG(t,e.text,e.role):oG(t,e.text,e)}async function rG(t,e,n){let r=t.getByRole(n,{name:e}),o=await r.count();if(o===0)return{outcome:"not_found",query:{kind:"semantic",text:e,role:n}};if(o===1)return{outcome:"resolved",locator:r};let s=await Em(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function oG(t,e,n){let r=t.getByRole("button",{name:e}),o=t.getByRole("link",{name:e}),s=t.getByLabel(e,{exact:!1}),[i,a,c]=await Promise.all([r.count(),o.count(),s.count()]);if(i+a+c===0)return{outcome:"not_found",query:n};let d=[];i>0&&d.push({loc:r,count:i}),a>0&&d.push({loc:o,count:a}),c>0&&d.push({loc:s,count:c});let u=await ZK(d);if(u.length===0)return{outcome:"not_found",query:n};if(u.length===1){let h=u[0];return h===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:h.locator.nth(h.index)}}let p=u.slice(0,5),f=[];for(let h=0;h<p.length;h++){let y=p[h];if(y===void 0)continue;let b=await wT(y.locator,y.index);if(b!==null){let S=`${b.role}:${b.label}:${h}`,k=0;for(let _=0;_<S.length;_++)k=k*31+S.charCodeAt(_)>>>0;f.push({...b,id:`el_${k.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var ST=m(()=>{"use strict"});async function xm(t,e,n,r){let o=t.url();if(o===n)return null;let s=ft(o,e);if(s.allowed)return null;try{await t.goBack()}catch{await r()}return{outcome:"blocked_by_policy",url:o,reason:s.reason}}var kT=m(()=>{"use strict";cn()});var Im={};qo(Im,{PlaywrightProvider:()=>Rm});function vT(t){switch(t.kind){case"semantic":return t.role!==void 0?`semantic('${t.text}', role='${t.role}')`:`semantic('${t.text}')`;case"element_id":return`element_id(${t.elementId})`;case"selector":return`selector(${t.selector})`}}var Rm,Cm=m(()=>{"use strict";fT();bT();ST();cn();kT();wm();Rm=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new Xc(e)}async open(e){let n=ft(e.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:e.url,reason:n.reason};let{sessionId:r}=e,o=await this.launcher.ensurePage(r),s=this.ensureSessionState(r),i=null,a=null;try{await o.goto(e.url,{timeout:e.timeoutMs??3e4,waitUntil:e.waitFor??"load"})}catch(u){a=u}let c=o.url();if(!(a!==null&&(c===""||c==="about:blank"))){let u=await xm(o,this.config,e.url,()=>this.close({sessionId:r}));if(u!==null)return u}(e.screenshot===!0||a!==null)&&(i=await this.captureScreenshot(o,r,"browser_open")),s.observationCounter+=1;let d=await zc(o,{observationCounter:s.observationCounter,screenshotPath:i,consoleErrors:this.launcher.getConsoleErrorCount(r),httpStatus:this.launcher.getLastHttpStatus(r),hasDialog:this.launcher.hasOpenDialog(r)});if(this.updateSessionFromObservation(s,d.interactive,d.url,d.title,"browser_open"),a!==null)throw a;return d}async observe(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_observe: no page open for session ${n}`);let o=this.ensureSessionState(n),s=null;e.screenshot===!0&&(s=await this.captureScreenshot(r,n,"browser_observe")),o.observationCounter+=1;let i=await zc(r,{observationCounter:o.observationCounter,screenshotPath:s,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n),includeHidden:e.includeHidden,maxElements:e.maxElements});return this.updateSessionFromObservation(o,i.interactive,i.url,i.title,"browser_observe"),i}async act(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_act: no page open for session ${n}`);let o=this.ensureSessionState(n),s=r.url(),i=e.timeoutMs??3e4,a=await Am(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${vT(e.target)}`);if(a.outcome==="ambiguous_target")return a;let{locator:c}=a,l=null,d=async()=>{switch(e.action){case"click":await c.click({timeout:i});break;case"fill":await c.fill(e.value??"");break;case"press":await c.press(e.value??"");break;case"select":await c.selectOption(e.value??"");break;case"hover":await c.hover({timeout:i});break;case"scroll_to":await c.scrollIntoViewIfNeeded({timeout:i});break;case"wait_for":await c.waitFor({timeout:i,state:"visible"});break}};try{await d()}catch(h){if(h instanceof Error&&/navigation|net::ERR/i.test(h.message))try{await d()}catch(y){l=y}else l=h}let u=await xm(r,this.config,s,()=>this.close({sessionId:n}));if(u!==null)return u;let p=null;(e.screenshot===!0||l!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await zc(r,{observationCounter:o.observationCounter,screenshotPath:p,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),g=`browser_act:${e.action}`;if(this.updateSessionFromObservation(o,f.interactive,f.url,f.title,g),l!==null)throw l;return f}async render(e){return this.launcher.renderHtml(e.url,{timeoutMs:e.timeoutMs??3e4,waitUntil:e.waitFor??"load",signal:e.signal,requestGuard:e.requestGuard})}async screenshot(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_screenshot: no page open for session ${n}`);let o=this.ensureSessionState(n),s;if(e.target!==void 0){let d=await Am(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${vT(e.target)}`);if(d.outcome==="ambiguous_target")throw new Error("screenshot target ambiguous; specify element_id or selector");s=await d.locator.screenshot()}else s=await r.screenshot({fullPage:e.fullPage??!1});let{path:i,bytes:a}=await Xr(n,s,"browser_screenshot"),c=0,l=0;if(e.fullPage===!0)try{let d=await r.evaluate(()=>({w:document.documentElement.scrollWidth,h:document.documentElement.scrollHeight}));c=d.w,l=d.h}catch{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}else{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}return{path:i,bytes:a,width:c,height:l,dataBase64:s.toString("base64"),mediaType:"image/png"}}async extract(e){throw new Error("browser_extract not implemented in Phase 1")}async close(e){await this.launcher.closeSession(e.sessionId),this.sessions.delete(e.sessionId)}describe(e){let n=this.sessions.get(e);if(n===void 0)return null;let r=this.launcher.getPage(e);return{active:r!==void 0,url:n.currentUrl,title:n.currentTitle,lastAction:n.lastAction,lastActionAt:n.lastActionAt,openTabs:r!==void 0?1:0}}async shutdown(){this.sessions.clear(),await this.launcher.shutdown()}ensureSessionState(e){let n=this.sessions.get(e);if(n!==void 0)return n;let r={observationCounter:0,knownElements:new Map,lastAction:null,lastActionAt:null,currentUrl:null,currentTitle:null};return this.sessions.set(e,r),r}updateSessionFromObservation(e,n,r,o,s){e.knownElements=new Map(n.map(i=>[i.id,i])),e.currentUrl=r,e.currentTitle=o,e.lastAction=s,e.lastActionAt=new Date().toISOString()}async captureScreenshot(e,n,r){try{let o=await e.screenshot({fullPage:!1}),{path:s}=await Xr(n,o,r);return s}catch{return null}}}});var Zn={};qo(Zn,{__resetBrowserRegistryForTests:()=>dG,browserProviderActive:()=>aG,closeBrowserProvider:()=>Mm,getBrowserProvider:()=>iG,getLastRoutingDecision:()=>lG,peekBrowserProvider:()=>cG});function _T(){Promise.resolve(Mm()).then(()=>{process.exit(130)})}function TT(){Promise.resolve(Mm()).then(()=>{process.exit(143)})}function ET(){Et=null}function sG(){Jc||(process.on("SIGINT",_T),process.on("SIGTERM",TT),process.on("exit",ET),Jc=!0)}function AT(){Jc&&(process.removeListener("SIGINT",_T),process.removeListener("SIGTERM",TT),process.removeListener("exit",ET),Jc=!1)}async function iG(t){return Et!==null?Et:(Qn!==null||(Qn=(async()=>{let e=gm(t),n=t?.surface??(t?.env??{}).AGENT_SURFACE??w.AGENT_SURFACE,r=await Q_({config:e,surface:n});Pm=r;let o;if(r.backend==="agent-browser"){let{AgentBrowserProvider:s}=await Promise.resolve().then(()=>(lT(),cT)),i=r.availability.connection;o=new s(e,i)}else{let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(Cm(),Im));o=new s(e)}return sG(),Et=o,Qn=null,o})()),Qn)}async function Mm(){if(Et===null)return;let t=Et;Et=null,Qn=null,AT(),await t.shutdown()}function aG(){return Et!==null}function cG(){return Et}function lG(){return Pm}function dG(){Et=null,Qn=null,Pm=null,AT()}var Et,Qn,Jc,Pm,er=m(()=>{"use strict";cn();Z_();P();Et=null,Qn=null,Jc=!1,Pm=null});async function xT(t,e){try{return await $_(t,e)}catch(n){return D("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function hG(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(er(),Zn)),r=await n();try{return await r.render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}catch(o){if(r.name==="agent-browser"){let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(Cm(),Im)),{loadBrowserConfig:i}=await Promise.resolve().then(()=>(cn(),hm)),a=i(),c=new s(a);try{return await c.render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}finally{await c.shutdown()}}throw o}}async function RT(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??hG,o=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},s=null,i="",a=t,c=null,l=null;try{let u=await an(n,t,{headers:gG,signal:e.signal},o);c=u.status,a=u.url||t;let p=u.headers.get("content-type")??"";if(u.ok){if(mG.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 u.text();if(fG.test(p)&&!pG.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await xT(f,a),e.signal.aborted)throw e.signal.reason??new Error("aborted")}}catch(u){if(e.signal.aborted||u instanceof ve||u instanceof Error&&u.message.startsWith("web_scrape markdown mode received binary"))throw u;l=u}if(!(s===null||s.textLength<200)&&s!==null){let u=um({html:i,extractedTextLength:s.textLength});return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1,...u!==void 0?{advisory:u}:{}}}try{await Ws(t,o);let u=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:f=>Ws(f,o)});u.finalUrl!==t&&/^https?:\/\//i.test(u.finalUrl)&&await Ws(u.finalUrl,o);let p=await xT(u.html,u.finalUrl);if(e.signal.aborted)throw e.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=um({html:u.html,extractedTextLength:p.textLength});return{title:p.title,markdown:p.markdown,finalUrl:u.finalUrl,usedRender:!0,...f!==void 0?{advisory:f}:{}}}}catch(u){if(e.signal.aborted||u instanceof ve)throw u;if(s===null){let p=u instanceof Error?u.message:String(u),f=l instanceof Error?l.message:`HTTP ${c??"error"}`,g=new Error(`web_scrape could not retrieve ${t}: fetch failed (${f}) and render failed (${p}).`);throw g.cause=u,g}}if(s!==null)return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1};throw new Error(`web_scrape could not retrieve any content from ${t} (HTTP ${c??"error"}).`)}var pG,fG,mG,gG,IT=m(()=>{"use strict";B_();pm();Vn();Q();pG=/(text\/html|application\/xhtml\+xml)/i,fG=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,mG=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,gG={"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 wG(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(yG,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json","x-api-key":t.apiKey,"User-Agent":"agent-afk/web_scrape"},body:JSON.stringify({query:n,type:"auto",numResults:Math.min(Math.max(r,1),bG),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let c="";try{let d=await s.text(),u=ue(d);u&&(c=`: ${u.length>200?u.slice(0,200)+"\u2026":u}`)}catch{}let l=s.statusText?` ${s.statusText}`:"";throw new Error(`Exa Search HTTP ${s.status}${l}${c}`)}let i;try{i=await s.json()}catch(c){throw new Error(`Exa Search response was not JSON: ${c instanceof Error?c.message:String(c)}`)}return(i.results??[]).slice(0,r).map(c=>({title:(c.title??"").trim()||"(untitled)",url:c.url??"",description:(c.highlights?.[0]??"").trim()})).filter(c=>c.url.length>0)}}}function CT(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?wG({apiKey:t.exaApiKey,fetchFn:t.fetchFn}):{error:'web_scrape search mode requires a search backend. Set EXA_API_KEY (free tier at https://exa.ai) to enable it. Use mode: "markdown" to read a known URL, or mode: "raw" for a direct fetch.'}}function PT(t,e){if(e.length===0)return`# Search results for "${t}"
|
|
284
284
|
|
|
285
285
|
(no results)`;let n=[`# Search results for "${t}"`,""];return e.forEach((r,o)=>{n.push(`## ${o+1}. ${r.title}`),r.url&&n.push(r.url),r.description&&n.push(r.description),n.push("")}),n.join(`
|
|
286
286
|
`).trimEnd()}var yG,bG,MT=m(()=>{"use strict";Qe();yG="https://api.exa.ai/search",bG=10});function Vc(t){if(t instanceof Error&&t.name==="TimeoutError")return"timeout";let e=t instanceof Error?t.message:String(t);return/Timeout\s+\d+\s*ms exceeded/i.test(e)?"timeout":void 0}var tr=m(()=>{"use strict";Tm()});function EG(t){if(!t||typeof t!="object")return{error:"Invalid input: expected an object"};let e=t,n=e.mode??"markdown";if(n!=="markdown"&&n!=="raw"&&n!=="search")return{error:`Invalid input: mode must be one of "markdown", "raw", "search" (got ${JSON.stringify(n)})`};let r=n,o,s;if(r==="search"){if(typeof e.query!="string"||e.query.length===0)return{error:'Invalid input: search mode requires a non-empty "query" string'};s=e.query}else{if(typeof e.url!="string"||e.url.length===0)return{error:`Invalid input: ${r} mode requires a non-empty "url" string`};let c;try{c=new URL(e.url)}catch{return{error:`Invalid input: "${e.url}" is not a valid absolute URL`}}if(c.protocol!=="http:"&&c.protocol!=="https:")return{error:`Invalid input: protocol "${c.protocol}" not supported (http/https only)`};o=c.toString()}let i=SG;if(e.timeout_ms!==void 0){if(typeof e.timeout_ms!="number"||!Number.isFinite(e.timeout_ms)||e.timeout_ms<=0)return{error:"Invalid input: timeout_ms must be a positive finite number"};i=Math.min(e.timeout_ms,kG)}let a=vG;if(e.max_bytes!==void 0){if(typeof e.max_bytes!="number"||!Number.isFinite(e.max_bytes)||e.max_bytes<=0)return{error:"Invalid input: max_bytes must be a positive finite number"};a=Math.min(e.max_bytes,_G)}return{mode:r,url:o,query:s,timeoutMs:i,maxBytes:a}}function Om(t,e){return Buffer.byteLength(t,"utf8")<=e?{content:t,truncated:!1}:{content:kt(t,e),truncated:!0}}function AG(t={}){let e=t.fetchFn??globalThis.fetch,n=t.env??process.env,r=t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{};return async(o,s)=>{if(typeof e!="function")return{content:"web_scrape unavailable: global fetch() is not present in this runtime (agent-afk requires Node 20+).",isError:!0};let i=EG(o);if("error"in i)return{content:i.error,isError:!0};if(s.aborted){let u=s.reason;return{content:`web_scrape aborted: ${u instanceof Error?u.message:String(u??"aborted")}`,isError:!0}}let a=new AbortController,c=()=>{a.abort(s.reason)},l,d=()=>{let u=a.signal.reason;return u instanceof Error?u.message:String(u??"aborted")};try{if(s.addEventListener("abort",c,{once:!0}),l=setTimeout(()=>{a.abort(new Error(`web_scrape timeout after ${i.timeoutMs}ms`))},i.timeoutMs),i.url!==void 0){let p=await Jn(i.url,r);if(a.signal.aborted)return{content:`web_scrape aborted: ${d()}`,isError:!0};if(!p.allowed)return{content:`web_scrape blocked: ${p.reason}`,isError:!0}}if(i.mode==="raw"){let p;try{let h={method:"GET",headers:{"User-Agent":"agent-afk/web_scrape",Accept:"*/*"},signal:a.signal};p=await an(e,i.url,h,r)}catch(h){return a.signal.aborted?{content:`web_scrape aborted: ${d()}`,isError:!0}:h instanceof ve?{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 ${i.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=Om(f,i.maxBytes);return{content:g.content,...g.truncated?{truncated:!0}:{}}}if(i.mode==="markdown")try{let p=await RT(i.url,{fetchFn:e,renderFn:t.renderFn,timeoutMs:i.timeoutMs,signal:a.signal,...t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{}});if(p.markdown.trim().length===0)return{content:`web_scrape extracted no readable content from ${i.url}.`,isError:!0};let f=Om(j_(p.markdown,p.advisory),i.maxBytes);return{content:f.content,...f.truncated?{truncated:!0}:{}}}catch(p){if(a.signal.aborted)return{content:`web_scrape aborted: ${d()}`,isError:!0};if(p instanceof ve)return{content:`web_scrape blocked: ${p.message}`,isError:!0};let f=p instanceof Error?p.message:String(p),g=Ue(p)&&!_m(f)?` (the render fallback needs the optional Playwright browser \u2014 run \`${Ks()}\`)`:"";return{content:`web_scrape markdown error: ${f}${g}`,isError:!0}}let u=CT({exaApiKey:n.EXA_API_KEY,fetchFn:e});if("error"in u)return{content:u.error,isError:!0};try{let p=await u.search(i.query,{limit:TG,timeoutMs:i.timeoutMs,signal:a.signal}),f=Om(PT(i.query,p),i.maxBytes);return{content:f.content,...f.truncated?{truncated:!0}:{}}}catch(p){return a.signal.aborted?{content:`web_scrape aborted: ${d()}`,isError:!0}:{content:`web_scrape search error (${u.name}): ${p instanceof Error?p.message:String(p)}`,isError:!0}}}finally{l!==void 0&&clearTimeout(l),s.removeEventListener("abort",c)}}}var SG,kG,vG,_G,TG,OT,DT=m(()=>{"use strict";IT();MT();Vn();vt();pm();tr();SG=3e4,kG=12e4,vG=1e5,_G=1e6,TG=10;OT=AG()});function IG(t){return xG.has(t)?"low":t==="DELETE"?"high":"medium"}function CG(t){return RG.has(t)}function OG(t){let e={};return t.forEach((n,r)=>{let o=r.toLowerCase();MG.has(o)||PG.some(s=>o.startsWith(s))||(e[r]=n)}),e}function DG(t,e){if(t==null)return{serialized:void 0,inferredContentType:void 0};let n=Object.keys(e).some(o=>o.toLowerCase()==="content-type");return typeof t=="string"?{serialized:t,inferredContentType:n?void 0:"text/plain"}:{serialized:JSON.stringify(t),inferredContentType:n?void 0:"application/json"}}function FG(t,e,n){let r=Buffer.byteLength(t,"utf8"),o=t,s=!1;if(r>n&&(o=kt(t,n),s=!0),!s&&/application\/json/i.test(e))try{return{body:JSON.parse(o),truncated:!1}}catch{}return{body:o,truncated:s}}async function NT(t){let{url:e,method:n,signal:r,domainCheck:o,recordEffect:s}=t,i=Math.min(t.maxResponseBytes??Dm,Fm),a={...t.headers},c=t.fetchFn??globalThis.fetch,l=t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{},d=IG(n);if(o!==void 0){let v=o(e);if(!v.allowed)throw Object.assign(new Error(`web_request blocked by domain policy: ${v.reason}`),{name:"DomainPolicyError"})}let u=await Jn(e,l);if(!u.allowed)throw new ve(u.reason);let{serialized:p,inferredContentType:f}=DG(t.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},y=CG(n)?{retries:2,baseDelayMs:300,maxDelayMs:5e3}:{retries:0},b=Date.now(),S;try{S=await an(c,e,g,{...l,retry:y})}catch(v){throw v instanceof ve,v}let k=Date.now()-b,_=S.headers.get("content-type")??"",E;try{let v=S.body?.getReader();if(!v)E="";else{let x=[],T=0,C=i*2;for(;;){let{done:N,value:O}=await v.read();if(N||!O)break;if(x.push(O),T+=O.byteLength,T>=C){await v.cancel();break}}E=new TextDecoder().decode(Buffer.concat(x,T))}}catch{E=""}let{body:R,truncated:A}=FG(E,_,i),F=OG(S.headers);return s!==void 0&&Promise.resolve(s({url:e,method:n,status:S.status,risk:d,timing_ms:k})).catch(()=>{}),{status:S.status,headers:F,body:R,truncated:A,timing_ms:k,risk:d}}function UT(t){if(typeof t!="string"||t.trim().length===0)return{error:"method must be a non-empty string (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS)"};let e=t.trim().toUpperCase(),n=["GET","POST","PUT","PATCH","DELETE","HEAD","OPTIONS"];return n.includes(e)?e:{error:`method "${t}" is not supported \u2014 must be one of: ${n.join(", ")}`}}var FT,LT,Dm,Fm,xG,RG,PG,MG,$T=m(()=>{"use strict";Vn();vt();FT=3e4,LT=12e4,Dm=1e5,Fm=1e6,xG=new Set(["GET","HEAD","OPTIONS"]),RG=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]);PG=["set-cookie","x-"],MG=new Set(["server","via","age","vary","authorization","www-authenticate"])});function LG(t){if(!t||typeof t!="object")return{error:"Invalid input: expected an object"};let e=t;if(typeof e.url!="string"||e.url.length===0)return{error:'Invalid input: "url" must be a non-empty string'};let n;try{n=new URL(e.url)}catch{return{error:`Invalid input: "${e.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=UT(e.method);if(typeof o=="object"&&"error"in o)return{error:`Invalid input: ${o.error}`};let s=o,i;if(e.body!==void 0&&e.body!==null){if(typeof e.body!="string"&&typeof e.body!="object")return{error:'Invalid input: "body" must be a string, object, or array'};i=e.body}let a={};if(e.headers!==void 0){if(typeof e.headers!="object"||e.headers===null||Array.isArray(e.headers))return{error:'Invalid input: "headers" must be a string-keyed object'};let u=e.headers;for(let[p,f]of Object.entries(u)){if(typeof f!="string")return{error:`Invalid input: header value for "${p}" must be a string`};a[p]=f}}let c=FT;if(e.timeout_ms!==void 0){if(typeof e.timeout_ms!="number"||!Number.isFinite(e.timeout_ms)||e.timeout_ms<=0)return{error:'Invalid input: "timeout_ms" must be a positive finite number'};c=Math.min(e.timeout_ms,LT)}let l=Dm;if(e.max_response_bytes!==void 0){if(typeof e.max_response_bytes!="number"||!Number.isFinite(e.max_response_bytes)||e.max_response_bytes<=0)return{error:'Invalid input: "max_response_bytes" must be a positive finite number'};l=Math.min(e.max_response_bytes,Fm)}let d;if(e.credential!==void 0){if(typeof e.credential!="string"||e.credential.length===0)return{error:'Invalid input: "credential" must be a non-empty string (an env var name)'};d=e.credential}return{url:r,method:s,body:i,headers:a,timeoutMs:c,maxResponseBytes:l,credential:d}}function NG(t={}){let e=t.fetchFn??globalThis.fetch,n=t.env??process.env;async function r(){if(t.domainCheck!==void 0)return t.domainCheck;try{let{loadBrowserConfig:o,enforceDomainPolicy:s}=await Promise.resolve().then(()=>(cn(),hm)),i=o();return a=>s(a,i)}catch{return}}return async(o,s)=>{if(typeof e!="function")return{content:"web_request unavailable: global fetch() is not present (agent-afk requires Node 20+).",isError:!0};let i=LG(o);if("error"in i)return{content:i.error,isError:!0};if(s.aborted){let p=s.reason;return{content:`web_request aborted: ${p instanceof Error?p.message:String(p??"aborted")}`,isError:!0}}let a={...i.headers};if(i.credential!==void 0){let p=n[i.credential];if(p===void 0||p.trim().length===0)return{content:`web_request credential error: environment variable "${i.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 c=new AbortController,l=()=>c.abort(s.reason),d,u=()=>{let p=c.signal.reason;return p instanceof Error?p.message:String(p??"aborted")};try{s.addEventListener("abort",l,{once:!0}),d=setTimeout(()=>{c.abort(new Error(`web_request timeout after ${i.timeoutMs}ms`))},i.timeoutMs);let p=await r(),f={url:i.url,method:i.method,body:i.body,headers:a,maxResponseBytes:i.maxResponseBytes,signal:c.signal,fetchFn:e,lookupFn:t.lookupFn,domainCheck:p,recordEffect:t.recordEffect},g;try{g=await NT(f)}catch(S){if(c.signal.aborted)return{content:`web_request aborted: ${u()}`,isError:!0};if(S instanceof ve)return{content:`web_request blocked: ${S.message}`,isError:!0};let k=S instanceof Error&&S.name==="DomainPolicyError"?"blocked":"network error",_=S instanceof Error?S.message:String(S);return{content:`web_request ${k}: ${_}`,isError:!0}}if(c.signal.aborted)return{content:`web_request aborted: ${u()}`,isError:!0};let h=g.body;if(typeof h=="string")h=ht(h);else if(typeof h=="object"&&h!==null){let S=ht(JSON.stringify(h));try{h=JSON.parse(S)}catch{h=S}}let y={status:g.status,headers:g.headers,body:h,timing_ms:g.timing_ms,...g.truncated?{truncated:!0}:{}};return{content:JSON.stringify(y,null,2),...g.truncated?{truncated:!0}:{}}}finally{d!==void 0&&clearTimeout(d),s.removeEventListener("abort",l)}}}var BT,jT=m(()=>{"use strict";$T();Vn();Mn();BT=NG()});import{existsSync as WT,mkdirSync as UG,readFileSync as $G,renameSync as BG,unlinkSync as jG,writeFileSync as HG}from"node:fs";import{dirname as HT,join as WG}from"node:path";import{randomBytes as KG}from"node:crypto";function nr(t){let e=t??mp();if(!WT(e))return[];try{let n=$G(e,"utf-8");return JSON.parse(n)}catch(n){let r=n instanceof Error?n.message:String(n);return console.error(`[schedule-store] failed to parse ${e}: ${r}`),[]}}function Gs(t,e){let n=e??mp();UG(HT(n),{recursive:!0});let r=WG(HT(n),`.schedules.json.${process.pid}.${KG(4).toString("hex")}.tmp`),o=JSON.stringify(t,null,2);try{HG(r,o,"utf-8"),BG(r,n)}catch(s){try{WT(r)&&jG(r)}catch{}throw s}}function KT(t,e){let n=nr(e),r=n.map(c=>c.id),o=GG(t.name),s=qG(o,r),i=new Date().toISOString(),a={...t,notifyOn:t.notifyOn??"failure",id:s,createdAt:i,updatedAt:i};return n.push(a),Gs(n,e),a}function GT(t,e){let n=nr(e),r=n.length,o=n.filter(s=>s.id!==t);return o.length===r?!1:(Gs(o,e),!0)}function qT(t,e){return nr(e).find(n=>n.id===t)}function GG(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"")}function qG(t,e){if(!e.includes(t))return t;let n=2;for(;e.includes(`${t}-${n}`);)n+=1;return`${t}-${n}`}function XT(t){return{taskId:t.id,command:t.command,trigger:t.trigger??"cron",...t.cron!==void 0?{cronExpression:t.cron}:{},...t.notifyOn!==void 0?{notifyOn:t.notifyOn}:{},...t.notifyChat!==void 0?{notifyChat:t.notifyChat}:{}}}var zT=m(()=>{"use strict";M()});import{existsSync as XG,readFileSync as zG}from"node:fs";import{join as JG}from"node:path";async function zr(t,e,n){let r,o;try{let s=JG(cw("default"),"port");if(!XG(s))return{synced:!1,detail:"daemon-not-detected (no port file)"};let i=zG(s,"utf-8").trim(),a=VG(i);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 s=r.includes(":")?`[${r}]`:r,i=await fetch(`http://${s}:${o}${e}`,{method:t,headers:{"Content-Type":"application/json"},body:n!==void 0?JSON.stringify(n):void 0,signal:AbortSignal.timeout(2e3)});return i.ok?{synced:!0,detail:"synced"}:t==="POST"&&i.status===409?{synced:!0,detail:"already-registered"}:t==="DELETE"&&i.status===404?{synced:!0,detail:"not-registered"}:{synced:!1,detail:`daemon-rejected (HTTP ${i.status})`}}catch{return{synced:!1,detail:"daemon-unreachable (stale port file or network error)"}}}function VG(t){let e=parseInt(t,10);if(String(e)===t&&!Number.isNaN(e))return e<1||e>65535?null:{host:"localhost",port:e};let n=t.lastIndexOf(":");if(n<1)return null;let r=t.slice(0,n),o=t.slice(n+1);if(!/^\d+$/.test(o))return null;let s=parseInt(o,10);return Number.isNaN(s)||s<1||s>65535||/^:+$/.test(r)?null:{host:r.startsWith("[")&&r.endsWith("]")?r.slice(1,-1):r,port:s}}var Lm,JT=m(()=>{"use strict";M();Lm="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 YG}from"node:fs";import{readFile as QG}from"node:fs/promises";var VT,YT,QT,ZT,eE=m(()=>{"use strict";zT();M();JT();VT=async(t,e)=>{if(!t||typeof t!="object")return{content:"Invalid input: expected object",isError:!0};let n=t;if(typeof n.name!="string"||!n.name)return{content:"Invalid input: name required",isError:!0};if(typeof n.command!="string"||!n.command)return{content:"Invalid input: command required",isError:!0};if(typeof n.cron!="string"||!n.cron)return{content:"Invalid input: cron required",isError:!0};let r=n.cron.trim().split(/\s+/);if(r.length!==5&&r.length!==6)return{content:"Invalid input: cron must be a 5 or 6-field expression",isError:!0};let o=n.notifyChat;if(o!==void 0&&typeof o!="number"&&typeof o!="string")return{content:"Invalid input: notifyChat must be a number (chat id) or string (chat id or alias name)",isError:!0};let s=KT({name:n.name,command:n.command,cron:n.cron,trigger:n.trigger??"cron",notifyOn:n.notifyOn,...o!==void 0?{notifyChat:o}:{},enabled:typeof n.enabled=="boolean"?n.enabled:!0}),i=s.enabled?await zr("POST","/tasks",{taskId:s.id,command:s.command,cron:s.cron,trigger:s.trigger,notifyOn:s.notifyOn,...s.notifyChat!==void 0?{notifyChat:s.notifyChat}:{}}):await zr("DELETE",`/tasks/${s.id}`);return{content:JSON.stringify({id:s.id,name:s.name,cron:s.cron,enabled:s.enabled,daemonSynced:i.synced,syncDetail:i.detail,...i.synced?{}:{syncNote:Lm}})}},YT=async(t,e)=>{let n=nr();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})))}},QT=async(t,e)=>{if(!t||typeof t!="object")return{content:"Invalid input: expected object",isError:!0};let n=t;if(typeof n.taskId!="string"||!n.taskId)return{content:"Invalid input: taskId required",isError:!0};let r=n.taskId,o=typeof n.limit=="number"?Math.min(Math.max(1,n.limit),50):10,s=ya();if(!YG(s))return{content:JSON.stringify([])};let i;try{let l=await QG(s);i=(l.length>1048576?l.subarray(l.length-1048576):l).toString("utf-8")}catch{return{content:JSON.stringify([])}}let a=i.split(`
|
package/dist/telegram.mjs
CHANGED
|
@@ -395,7 +395,7 @@ ${o}`,paths:[e,n]}:o!==null?s={content:o,paths:[n]}:r!==null?s={content:r,paths:
|
|
|
395
395
|
|
|
396
396
|
${e}`}var mV,ty=h(()=>{"use strict";mV=new Set(["script","style","noscript","template","svg"])});function yV(t,e){return new Promise((n,r)=>{if(e?.aborted){r(e.reason??new Error("aborted"));return}let o=()=>{clearTimeout(s),r(e?.reason??new Error("aborted"))},s=setTimeout(()=>{e?.removeEventListener("abort",o),n()},t);e?.addEventListener("abort",o,{once:!0})})}function iR(t,e,n){let r=Math.min(e*2**t,n);return Math.round(Math.random()*r)}function bV(t,e){let n=t.headers.get("retry-after");if(n===null)return null;let r=Number(n.trim());return!Number.isFinite(r)||r<0?null:Math.min(r*1e3,e)}async function aR(t,e,n={},r={}){let o=r.retries??3,s=r.baseDelayMs??500,i=r.maxDelayMs??1e4,a=r.sleep??yV,c=n.signal??void 0,l;for(let d=0;d<=o;d++){if(c?.aborted)throw c.reason??new Error("aborted");try{let u=await t(e,n);if(!hV.has(u.status)||d===o)return u;let p=bV(u,i)??iR(d,s,i);O("[web/retryFetch] retrying",{url:e,attempt:d,status:u.status,waitMs:p}),await u.body?.cancel().catch(()=>{}),await a(p,c)}catch(u){if(c?.aborted||(l=u,d===o))throw u;let p=iR(d,s,i);O("[web/retryFetch] retrying after error",{url:e,attempt:d,waitMs:p}),await a(p,c)}}throw l??new Error("retryFetch: exhausted without a result")}var hV,cR=h(()=>{"use strict";se();hV=new Set([429,502,503,504])});import{BlockList as wV,isIP as ry}from"node:net";import{lookup as SV}from"node:dns/promises";import{Agent as kV}from"undici";function dR(){let t=k.AFK_WEB_ALLOW_PRIVATE_HOSTS?.trim().toLowerCase();return t==="1"||t==="true"}function _V(t){return t.startsWith("[")&&t.endsWith("]")?t.slice(1,-1):t}function ny(t){let e=ry(t);return e===0?!1:EV.check(t,e===4?"ipv4":"ipv6")}async function uR(t){return SV(t,{all:!0,verbatim:!0})}async function Nr(t,e={}){if(e.allowPrivateHosts??dR())return{allowed:!0};let n;try{n=new URL(t)}catch{return{allowed:!1,reason:`"${t}" is not a valid absolute URL`}}if(n.protocol!=="http:"&&n.protocol!=="https:")return{allowed:!1,reason:`protocol "${n.protocol}" not supported (http/https only)`};let r=_V(n.hostname),o=(a,c)=>`refusing to fetch ${c} \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(ry(r)!==0)return ny(r)?{allowed:!1,reason:o(r,r)}:{allowed:!0};let s=e.lookupFn??uR,i;try{i=await s(r)}catch{return{allowed:!0}}for(let a of i)if(ny(a.address))return{allowed:!1,reason:o(a.address,`${r} (resolved)`)};return{allowed:!0}}async function oa(t,e={}){let n=await Nr(t,e);if(!n.allowed)throw new Pe(n.reason)}async function Un(t,e,n={},r={}){let o={...r.lookupFn!==void 0?{lookupFn:r.lookupFn}:{},...r.allowPrivateHosts!==void 0?{allowPrivateHosts:r.allowPrivateHosts}:{}},s=e;for(let i=0;i<=lR;i++){await oa(s,o);let a={...n,redirect:"manual",...t===globalThis.fetch&&!(r.allowPrivateHosts??dR())?{dispatcher:xV}:{}},c=await aR(t,s,a,r.retry??{});if(!AV.has(c.status))return c;let l=c.headers.get("location");if(l===null||l.trim()==="")return c;let d;try{d=new URL(l,c.url||s).toString()}catch{return c}await c.body?.cancel().catch(()=>{}),s=d}throw new Pe(`too many redirects (>${lR}) starting from ${e}`)}var vV,TV,EV,Pe,xV,lR,AV,$r=h(()=>{"use strict";F();cR();vV=[["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]],TV=[["::",96],["64:ff9b::",96],["fc00::",7],["fe80::",10]],EV=(()=>{let t=new wV;for(let[e,n]of vV)t.addSubnet(e,n,"ipv4");for(let[e,n]of TV)t.addSubnet(e,n,"ipv6");return t})(),Pe=class extends Error{constructor(e){super(e),this.name="EgressBlockedError"}};xV=new kV({connect:{lookup(t,e,n){uR(t).then(r=>{let o=r.find(i=>ny(i.address));if(o!==void 0){n(new Pe(`refusing to connect to ${t} (resolved) \u2014 internal/private address ${o.address} (loopback, link-local, cloud metadata, or RFC1918 space). Set AFK_WEB_ALLOW_PRIVATE_HOSTS=1 to allow private-host access.`),"",0);return}let s=r[0];if(s===void 0){n(new Error(`DNS lookup returned no addresses for ${t}`),"",0);return}n(null,s.address,ry(s.address))},r=>n(r,"",0))}}});lR=20,AV=new Set([301,302,303,307,308])});var sy={};yo(sy,{enforceDomainPolicy:()=>It,loadBrowserConfig:()=>oy});import{readFileSync as RV}from"node:fs";import{join as IV}from"path";function PV(t){let n=t.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function pR(t,e){return PV(e).test(t)}function OV(t,e){if(t!==void 0){let n=t.trim().toLowerCase();if(n==="1"||n==="true"||n==="yes")return!0;if(n==="0"||n==="false"||n==="no")return!1}if(e!==void 0){if(CV.has(e))return!0;if(MV.has(e))return!1}return!1}function fR(t){return t===void 0||t.trim()===""?[]:t.split(",").map(e=>e.trim().toLowerCase()).filter(e=>e.length>0)}function DV(t){if(t===void 0||t==="")return"auto";if(t==="playwright"||t==="agent-browser"||t==="auto")return t;throw new Error(`AFK_BROWSER_BACKEND: must be "playwright", "agent-browser", or "auto", got: ${t}`)}function mR(t){let e=t===void 0||t.trim()===""?"default":t.trim();return Hm(e),e}function FV(t){if(t===void 0)return!1;let e=t.trim().toLowerCase();return e==="1"||e==="true"||e==="yes"}function LV(t){try{return RV(t,"utf8")}catch(e){if(e.code==="ENOENT")return;throw e}}function NV(t,e){let n={...t};if(typeof e.headless=="boolean"&&(n.headless=e.headless),Array.isArray(e.allowedDomains)&&(n.allowedDomains=e.allowedDomains.filter(r=>typeof r=="string").map(r=>r.trim().toLowerCase()).filter(r=>r.length>0)),Array.isArray(e.blockedDomains)&&(n.blockedDomains=e.blockedDomains.filter(r=>typeof r=="string").map(r=>r.trim().toLowerCase()).filter(r=>r.length>0)),typeof e.domSnapshots=="boolean"&&(n.domSnapshots=e.domSnapshots),e.backend==="playwright"||e.backend==="agent-browser"||e.backend==="auto")n.backend=e.backend;else if(e.backend!==void 0)throw new Error(`AFK_BROWSER_BACKEND: must be "playwright", "agent-browser", or "auto", got: ${String(e.backend)}`);return typeof e.defaultProfile=="string"&&(n.defaultProfile=mR(e.defaultProfile)),n}function oy(t){let e=t?.env??k,n=t?.readFileSync??LV,r=t?.surface??e.AGENT_SURFACE,o=OV(e.AFK_BROWSER_HEADLESS,r),s=fR(e.AFK_BROWSER_ALLOWED_DOMAINS),i=fR(e.AFK_BROWSER_BLOCKED_DOMAINS),a=FV(e.AFK_BROWSER_DOM_SNAPSHOTS),c=DV(e.AFK_BROWSER_BACKEND),l=mR(e.AFK_BROWSER_DEFAULT_PROFILE),d={headless:o,allowedDomains:s,blockedDomains:i,domSnapshots:a,backend:c,configPath:null,defaultProfile:l},u=e.AFK_BROWSER_CONFIG,p=u!==void 0&&u.trim()!==""?u.trim():IV(sn(),"browser.json"),f=n(p);if(f===void 0)return d;let m;try{m=JSON.parse(f)}catch(y){throw new Error(`Failed to parse browser config at ${p}: ${String(y)}`)}if(typeof m!="object"||m===null||Array.isArray(m))throw new Error(`Browser config at ${p} must be a JSON object`);let g=NV(d,m);return g.configPath=p,g}function It(t,e){let n;try{n=new URL(t).hostname.toLowerCase()}catch{return{allowed:!1,reason:`invalid URL: ${t}`}}for(let r of e.blockedDomains)if(pR(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return e.allowedDomains.length>0&&!e.allowedDomains.some(o=>pR(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var CV,MV,Bn=h(()=>{"use strict";F();L();CV=new Set(["daemon","subagent","telegram","afk"]),MV=new Set(["repl","interactive","cli"])});import{readFileSync as $V}from"node:fs";import{join as UV}from"node:path";import{homedir as BV}from"node:os";function HV(t){let e=t??jV,n;try{n=$V(e,"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 s;try{s=new URL(o.url)}catch{return null}let{hostname:i,protocol:a}=s;if(!(i==="127.0.0.1"||i==="localhost"||i==="::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 WV(t){try{return process.kill(t,0),!0}catch{return!1}}async function KV(t,e,n=2e3){try{let r=new AbortController,o=setTimeout(()=>r.abort(),n),s=await fetch(`${t}/health`,{method:"GET",headers:{Authorization:`Bearer ${e}`,Host:"127.0.0.1:8833"},signal:r.signal});return clearTimeout(o),s.ok}catch{return!1}}async function iy(t){let e=HV(t);return e===null?{available:!1,connection:null,reason:"connection file missing or invalid"}:WV(e.pid)?await KV(e.url,e.token)?{available:!0,connection:e,reason:null}:{available:!1,connection:e,reason:`health probe failed at ${e.url}`}:{available:!1,connection:e,reason:`stale connection file: PID ${e.pid} not alive`}}var jV,gR=h(()=>{"use strict";jV=UV(BV(),".config","agent-browser","connection.json")});async function hR(t){let{config:e,surface:n}=t;if(e.backend==="playwright")return{backend:"playwright",reason:"explicit config: backend=playwright",probeMs:0,availability:null};if(e.backend==="agent-browser"){let i=Date.now(),a=await iy(),c=Date.now()-i;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:c,availability:a}}if(n&&GV.has(n))return{backend:"playwright",reason:`auto: surface "${n}" excluded from Agent Browser`,probeMs:0,availability:null};if(e.headless)return{backend:"playwright",reason:"auto: headless mode requires Playwright",probeMs:0,availability:null};let r=Date.now(),o=await iy(),s=Date.now()-r;return o.available?{backend:"agent-browser",reason:"auto: Agent Browser available and preferred",probeMs:s,availability:o}:{backend:"playwright",reason:`auto: Agent Browser unavailable (${o.reason})`,probeMs:s,availability:o}}var GV,yR=h(()=>{"use strict";gR();GV=new Set(["daemon","subagent"])});import{createHash as qV}from"crypto";function bR(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&XV.test(t.label))}function wR(t){return qV("sha256").update(t,"utf8").digest("hex").slice(0,8)}function SR(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var XV,$d=h(()=>{"use strict";XV=/password|secret|token|api[_-]?key|otp|2fa/i});import{randomBytes as zV}from"crypto";import{mkdir as JV,stat as VV,writeFile as YV}from"fs/promises";import{join as ay}from"path";import{gzip as QV}from"zlib";import{promisify as ZV}from"util";function e4(t){return ay(it(t),"browser")}function t4(t){return ay(e4(t),"screenshots")}function n4(){return new Date().toISOString().replace(/[:.]/g,"-")}function r4(){return zV(3).toString("hex")}async function Yo(t,e,n){if(e.length>kR)throw new Error(`writeScreenshotSidecar: buffer exceeds ${kR} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=t4(t);await JV(r,{recursive:!0});let o=`${n4()}-${r4()}-${n}.png`,s=ay(r,o);await YV(s,e);let{size:i}=await VV(s);return{path:s,bytes:i}}var uwe,kR,cy=h(()=>{"use strict";L();$d();uwe=ZV(QV);kR=5*1024*1024});var Ud,vR=h(()=>{"use strict";se();Ud=class{baseUrl;token;constructor(e){this.baseUrl=e.url,this.token=e.token}async call(e,n,r=3e4){let o={version:1,method:e,params:n},s=new AbortController,i=setTimeout(()=>s.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:s.signal});if(!a.ok){let l=await a.text().catch(()=>"");throw new Error(`Agent Browser ${e} failed (HTTP ${a.status}): ${l}`)}let c=await a.json();if(c.ok===!1){let l=c.error,d=l?.code??"UNKNOWN",u=l?.message??JSON.stringify(c);throw new Error(`Agent Browser ${e} failed: [${String(d)}] ${String(u)}`)}return c.result}finally{clearTimeout(i)}}async listTabs(){return this.call("tabs.list",null)}async openTab(e){return{tabId:(await this.call("tabs.open",{url:e},6e4)).id}}async closeTab(e){await this.call("page.eval",{id:e,script:"window.close()"}).catch(n=>{O("[browser/agent-browser] closeTab window.close() failed (tab leak expected)",{tabId:e,err:n})})}async read(e,n){return this.call("page.read",{id:e,mode:n?.mode??"main",...n?.query?{query:n.query}:{},...n?.budget?{budget:n.budget}:{}})}async inspect(e,n){return this.call("page.inspect",{id:e,mode:n?.mode??"interactive",...n?.query?{query:n.query}:{},...n?.limit?{limit:n.limit}:{}})}async click(e,n){await this.call("page.click",{id:e,elementId:n})}async fill(e,n,r){await this.call("page.fill",{id:e,elementId:n,value:r})}async press(e,n,r){await this.call("page.press",{id:e,key:n,...r?{elementId:r}:{}})}async select(e,n,r){await this.call("page.select",{id:e,elementId:n,value:r})}async waitFor(e,n,r){await this.call("page.wait",{id:e,condition:n,...r?.value?{value:r.value}:{},...r?.timeout?{timeout:r.timeout}:{}},(r?.timeout??3e4)+5e3)}async evalScript(e,n){return this.call("page.eval",{id:e,script:n})}async screenshot(e){return this.call("page.screenshot",{id:e})}}});function ly(t){return{id:t.id,role:t.role,label:t.label,kind:t.kind,value:t.value,state:{disabled:t.disabled,...t.checked!==void 0?{checked:t.checked}:{},...t.selected!==void 0?{selected:t.selected}:{},...t.expanded!==void 0?{expanded:t.expanded}:{}},bbox:t.bbox,...t.selector?{selector:t.selector}:{}}}function TR(t,e){switch(e.kind){case"element_id":if(t.has(e.elementId))return e.elementId;throw new Error(`Element ${e.elementId} not found in current observation. Call browser_observe to refresh.`);case"selector":return null;case"semantic":return null}}async function dy(t,e,n,r,o,s){switch(n){case"click":await t.click(e,r);break;case"fill":if(o===void 0)throw new Error("fill requires a value");await t.fill(e,r,o);break;case"press":if(o===void 0)throw new Error("press requires a value (key combo)");await t.press(e,o,r);break;case"select":if(o===void 0)throw new Error("select requires a value");await t.select(e,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 i=r.replace(/\\/g,"\\\\").replace(/"/g,'\\"');await t.evalScript(e,`document.querySelector('[data-element-id="${i}"]')?.scrollIntoView({behavior:'smooth',block:'center'})`);break}case"wait_for":await t.waitFor(e,"element",{value:r,timeout:s??1e4});break;default:throw new Error(`Unknown action: ${n}`)}}async function ER(t,e){if(e.target.kind!=="semantic")throw new Error("resolveSemanticAndAct called with non-semantic target");let{elements:n}=await t.client.inspect(t.tabId,{mode:"interactive",query:e.target.text,limit:10}),r=n;if(e.target.role){let c=e.target.role.toLowerCase();r=n.filter(l=>l.role.toLowerCase()===c)}if(r.length===0)throw new Error(`No element found matching semantic target: text="${e.target.text}"`+(e.target.role?`, role="${e.target.role}"`:""));if(r.length>1)return{outcome:"ambiguous_target",query:{text:e.target.text,...e.target.role?{role:e.target.role}:{}},candidates:r.slice(0,5).map(ly)};let s=r[0].id;await dy(t.client,t.tabId,e.action,s,e.value,e.timeoutMs);let i=await t.client.read(t.tabId,{mode:"main"}),a=It(i.url,t.config);return a.allowed?{elementId:s}:{outcome:"blocked_by_policy",url:i.url,reason:`action navigated to blocked domain: ${a.reason}`}}var _R=h(()=>{"use strict";Bn()});var xR={};yo(xR,{AgentBrowserProvider:()=>uy});var uy,AR=h(()=>{"use strict";Bn();cy();vR();_R();uy=class{name="agent-browser";config;client;sessions=new Map;constructor(e,n){this.config=e,this.client=new Ud(n)}async open(e){let n=It(e.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:e.url,reason:n.reason};let r=this.sessions.get(e.sessionId);if(r)await this.client.evalScript(r.tabId,`window.location.href = ${JSON.stringify(e.url)}`),await this.client.waitFor(r.tabId,"load",{timeout:e.timeoutMs??3e4});else{let{tabId:i}=await this.client.openTab(e.url);await this.client.waitFor(i,"load",{timeout:e.timeoutMs??3e4}),r={tabId:i,observationCounter:0,knownElements:new Map,lastAction:null,lastActionAt:null,currentUrl:null,currentTitle:null},this.sessions.set(e.sessionId,r)}let o=await this.client.read(r.tabId,{mode:"main"}),s=It(o.url,this.config);return s.allowed?this.buildObservation(r,e.sessionId,e.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: ${s.reason}`})}async observe(e){let n=this.sessions.get(e.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${e.sessionId}. Call browser_open first.`);return this.buildObservation(n,e.sessionId,e.screenshot,e.maxElements,"browser_observe")}async act(e){let n=this.sessions.get(e.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${e.sessionId}. Call browser_open first.`);let r=TR(n.knownElements,e.target);if(r===null){if(e.target.kind==="semantic"){let i=await ER({client:this.client,config:this.config,tabId:n.tabId},e);return"outcome"in i?i:(n.lastAction=`browser_act:${e.action}`,n.lastActionAt=new Date().toISOString(),this.buildObservation(n,e.sessionId,e.screenshot,void 0,"browser_act"))}throw e.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(e.target)}`)}await dy(this.client,n.tabId,e.action,r,e.value,e.timeoutMs),n.lastAction=`browser_act:${e.action}`,n.lastActionAt=new Date().toISOString();let o=await this.client.read(n.tabId,{mode:"main"}),s=It(o.url,this.config);return s.allowed?this.buildObservation(n,e.sessionId,e.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: ${s.reason}`})}async render(e){throw new Error("AgentBrowserProvider does not support render(). Use PlaywrightProvider for one-shot content fetches.")}async screenshot(e){let n=this.sessions.get(e.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${e.sessionId}. Call browser_open first.`);if(e.target!==void 0||e.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"),s=o.length>=24?o.readUInt32BE(16):0,i=o.length>=24?o.readUInt32BE(20):0;return{path:(await Yo(e.sessionId,o,"browser_screenshot")).path,bytes:o.length,width:s,height:i,dataBase64:r.data,mediaType:"image/png"}}async extract(e){throw new Error("AgentBrowserProvider does not support extract() yet.")}async close(e){let n=this.sessions.get(e.sessionId);if(n){try{await this.client.closeTab(n.tabId)}catch{}this.sessions.delete(e.sessionId)}}describe(e){let n=this.sessions.get(e);return n?{active:!0,url:n.currentUrl,title:n.currentTitle,lastAction:n.lastAction,lastActionAt:n.lastActionAt,openTabs:1}:null}async shutdown(){let e=Array.from(this.sessions.entries()).map(async([,n])=>{try{await this.client.closeTab(n.tabId)}catch{}});await Promise.all(e),this.sessions.clear()}async buildObservation(e,n,r,o,s="browser_open"){let[i,a]=await Promise.all([this.client.read(e.tabId,{mode:"main",budget:4e3}),this.client.inspect(e.tabId,{mode:"interactive",limit:o??80})]),c=a.elements.map(ly),l=o??80,d=c.slice(0,l);e.observationCounter+=1,e.knownElements=new Map(d.map(g=>[g.id,g])),e.currentUrl=i.url,e.currentTitle=i.title;let u=[];c.length>l&&u.push(`page has ${c.length} interactive elements; showing first ${l}`);let p=null;if(r)try{let g=await this.client.screenshot(e.tabId),y=Buffer.from(g.data,"base64");p=(await Yo(n,y,s)).path}catch{u.push("screenshot capture failed")}let f=`obs_${e.observationCounter.toString(36)}`,m={httpStatus:null,loadingState:"idle",hasDialog:!1,consoleErrors:0};return{observationId:f,url:i.url,title:i.title,textSummary:i.content.slice(0,4e3),interactive:d,status:m,warnings:u,screenshotPath:p,capturedAt:new Date().toISOString()}}}});import{existsSync as o4,readFileSync as s4}from"node:fs";import{createRequire as i4}from"node:module";import{dirname as a4,join as c4}from"node:path";function PR(t){if(typeof t=="string")return t;let e=[],n=t;for(let r=0;r<d4&&n instanceof Error;r++)e.push(n.message),n=n.cause;return e.length>0?e.join(" | "):String(t)}function ze(t){let e=PR(t);return IR.some(n=>e.includes(n))}function u4(){try{let e=i4(import.meta.url).resolve("playwright/package.json"),n=JSON.parse(s4(e,"utf8"));if(typeof n!="object"||n===null)return;let r=n.bin,o=typeof r=="string"?r:typeof r=="object"&&r!==null?r.playwright:void 0;if(typeof o!="string"||o.length===0)return;let s=c4(a4(e),o);return o4(s)?`node ${/\s/.test(s)?`"${s}"`:s} install chromium`:void 0}catch{return}}function sa(){return RR??=u4()??l4,RR}function py(t){return t.includes("install chromium")}function gt(t,e){let n=PR(t),r=e?.latched===!0?` ${p4}`:"";if(n.includes("Executable doesn't exist")){let o="";return e?.headless===!0?o=" This launch was headless, which needs the `chromium_headless_shell-*` build.":e?.headless===!1&&(o=" This launch was headed, which needs the full `chromium-*` build \u2014 the headless shell alone does not satisfy it."),`browser tools require the Playwright chromium binary. Install via: ${sa()}.${o}${r}`}return`browser tools require the optional \`playwright\` peer dependency. Install via: pnpm add playwright (then ${sa()}). Or pick a different tool.${r}`}function Bd(t,e,n=!1){if(!ze(t))return t;let r=t instanceof Error?t.message:String(t);return new Error(`${r}
|
|
397
397
|
|
|
398
|
-
${gt(t,{headless:e,latched:n})}`,{cause:t})}var IR,l4,d4,RR,p4,fy=h(()=>{"use strict";IR=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],l4="pnpm exec playwright install chromium",d4=4;p4="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 Ur from"node:fs";import jd from"node:path";import{randomBytes as f4}from"node:crypto";function m4(){try{return"5.216.1"}catch{}try{let t=jd.resolve(import.meta.dirname,"../../../package.json"),e=Ur.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var g4,Hd,CR=h(()=>{"use strict";fy();L();se();g4=m4(),Hd=class{config;browser;sessions=new Map;launchPromise;launchFailure;shutdownComplete=!1;constructor(e){this.config=e}clearLaunchFailure(){this.launchFailure=void 0}latchLaunchFailure(e){this.launchFailure={error:e}}async ensureBrowser(){if(this.browser!==void 0&&this.browser.isConnected())return this.browser;if(this.launchFailure!==void 0)throw this.launchFailure.error;return this.browser!==void 0&&!this.browser.isConnected()&&(this.browser=void 0,this.launchPromise=void 0),this.launchPromise!==void 0?this.launchPromise:(this.launchPromise=(async()=>{let e;try{({chromium:e}=await import("playwright"))}catch(n){let r=Bd(n,this.config.headless,!0);throw this.latchLaunchFailure(r),this.launchPromise=void 0,r}try{let n=await e.launch({headless:this.config.headless});return this.browser=n,this.clearLaunchFailure(),n}catch(n){let r=Bd(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(e){let n=this.sessions.get(e);if(n!==void 0)return n.context;let r=await this.ensureBrowser(),o=this.loadStorageState(this.config.defaultProfile),s=await r.newContext({...this.contextOptions(),...o!==void 0?{storageState:o}:{}}),i={context:s,page:void 0,consoleErrors:0,lastHttpStatus:null,openDialog:void 0};return this.sessions.set(e,i),s}async ensurePage(e){let n=this.sessions.get(e);if(n!==void 0&&n.page!==void 0)return n.page;await this.ensureContext(e);let r=this.sessions.get(e);if(r===void 0)throw new Error(`[BrowserLauncher] session entry disappeared for sessionId=${e}`);if(r.page!==void 0)return r.page;let o=await r.context.newPage();return r.page=o,o.on("console",s=>{s.type()==="error"&&(r.consoleErrors+=1)}),o.on("request",s=>{s.isNavigationRequest()&&s.frame()===o.mainFrame()&&(r.lastHttpStatus=null)}),o.on("response",s=>{s.frame()===o.mainFrame()&&s.request().isNavigationRequest()&&(r.lastHttpStatus=s.status())}),o.on("dialog",s=>{r.openDialog=s}),o}getPage(e){return this.sessions.get(e)?.page}async renderHtml(e,n){let o=await(await this.ensureBrowser()).newContext(this.contextOptions()),s;n.requestGuard!==void 0&&await o.route("**/*",async a=>{try{await n.requestGuard(a.request().url()),await a.continue()}catch(c){s=c,await a.abort("blockedbyclient")}});let i=()=>{o.close().catch(()=>{})};if(n.signal?.aborted===!0)throw await o.close().catch(()=>{}),new Error("render aborted");n.signal!==void 0&&n.signal.addEventListener("abort",i,{once:!0});try{let a=await o.newPage(),c;try{c=await a.goto(e,{timeout:n.timeoutMs,waitUntil:n.waitUntil})}catch(p){throw s??p}if(s!==void 0)throw s;let l=await a.content();if(s!==void 0)throw s;let d=a.url(),u=c!==null?c.status():null;return{html:l,finalUrl:d,httpStatus:u}}finally{n.signal!==void 0&&n.signal.removeEventListener("abort",i),await o.close().catch(()=>{})}}getConsoleErrorCount(e){return this.sessions.get(e)?.consoleErrors??0}getLastHttpStatus(e){return this.sessions.get(e)?.lastHttpStatus??null}hasOpenDialog(e){return this.sessions.get(e)?.openDialog!==void 0}async dismissDialog(e,n=!0){let r=this.sessions.get(e);if(r===void 0||r.openDialog===void 0)return;let o=r.openDialog;r.openDialog=void 0,n?await o.accept():await o.dismiss()}async closeSession(e){this.clearLaunchFailure();let n=this.sessions.get(e);n!==void 0&&(this.sessions.delete(e),await this.saveStorageState(this.config.defaultProfile,n.context),n.page!==void 0&&await n.page.close().catch(()=>{}),await n.context.close().catch(()=>{}))}async shutdown(){if(this.clearLaunchFailure(),this.shutdownComplete)return;this.shutdownComplete=!0;let e=[...this.sessions.keys()];if(await Promise.all(e.map(n=>this.closeSession(n))),this.browser!==void 0){let n=this.browser;this.browser=void 0,await n.close().catch(()=>{})}}activeSessions(){return this.sessions.size}contextOptions(){return{viewport:{width:1280,height:800},userAgent:`Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 agent-afk/${g4}`}}loadStorageState(e){let n=Wm(e);try{if(!Ur.existsSync(n))return;let r=JSON.parse(Ur.readFileSync(n,"utf8"));return O("[browser/vault] restored session",{profile:e,file:n}),r}catch(r){O("[browser/vault] ignoring unreadable vault",{profile:e,file:n,err:r});return}}async saveStorageState(e,n){try{let r=Wm(e);if(!Ur.existsSync(r))return;let o=await n.storageState(),s=jd.join(jd.dirname(r),`.${jd.basename(r)}.${process.pid}.${f4(4).toString("hex")}.tmp`);Ur.writeFileSync(s,JSON.stringify(o),{mode:384}),Ur.chmodSync(s,384),Ur.renameSync(s,r),O("[browser/vault] saved session",{profile:e,file:r})}catch(r){O("[browser/vault] save failed",{profile:e,err:r})}}}});import{createHash as h4}from"node:crypto";function y4(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function b4(t,e,n){return`el_${h4("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function w4(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function MR(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function DR(t,e){let n=t.role??"",r=t.name??"";OR.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])DR(s,e)}async function S4(t){return t.evaluate(e=>{let n=Array.from(document.querySelectorAll(e)),r=[];for(let o of n){let s=o.getBoundingClientRect(),i=o;if(s.width===0&&s.height===0){let d=window.getComputedStyle(i);if(d.display==="none"||d.visibility==="hidden")continue}let a=o.tagName.toLowerCase(),c=o.getAttribute("aria-label")??o.getAttribute("placeholder")??(o.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a==="input"?o.type||null:o.getAttribute("type");r.push({name:c,tagName:a,type:l,id:o.id||null,testId:o.getAttribute("data-testid"),bbox:{x:Math.round(s.left),y:Math.round(s.top),w:Math.round(s.width),h:Math.round(s.height)}})}return r},FR).catch(()=>[])}async function k4(t){return t.evaluate(e=>{let n={button:"button",a:"link",input:"textbox",textarea:"textbox",select:"combobox"},r=Array.from(document.querySelectorAll(e)),o=[];for(let s of r){let i=s.tagName.toLowerCase(),a=s.getAttribute("role")??"",c=s.getAttribute("aria-label")??s.getAttribute("placeholder")??(s.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a||(n[i]??"");if(i==="input"){let g=s.type;g==="checkbox"?l="checkbox":g==="radio"?l="radio":g==="button"||g==="submit"||g==="reset"?l="button":g==="search"?l="searchbox":l="textbox"}if(!l)continue;let d="value"in s?s.value:void 0,u=d!==void 0?String(d):void 0,p=s.disabled??!1,f=i==="input"?s.checked:void 0,m={role:l,name:c,disabled:p};u!==void 0&&(m.value=u),f!==void 0&&(m.checked=f),o.push(m)}return o},FR).catch(()=>[])}function v4(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function Wd(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=v4(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=S4(t),c=t.evaluate(()=>document.body?.innerText??"").catch(()=>""),l=Promise.resolve(t.url()),d=t.title().catch(()=>""),[u,p,f,m,g]=await Promise.all([i,a,c,l,d]),y,b=!1;u!==null?(y=[],DR(u,y)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,y=(await k4(t)).filter(C=>OR.has(C.role??"")));let w=new Map;for(let E of p){let C=MR(E.name),H=w.get(C);(!H||H.bbox.w===0&&E.bbox.w>0)&&w.set(C,E)}let v=y.map(E=>({ax:E,dom:w.get(MR(E.name??""))})),x=r?v:v.filter(E=>E.dom?E.dom.bbox.w>0||E.dom.bbox.h>0:!0);x.sort((E,C)=>{let H=E.dom?.bbox.y??0,M=C.dom?.bbox.y??0;if(H!==M)return H-M;let $=E.dom?.bbox.x??0,U=C.dom?.bbox.x??0;return $-U}),x.length>200&&o.push("page has 200+ interactive elements; consider scoping");let _=x.slice(0,n).map((E,C)=>{let H=E.ax.role??"generic",M=E.ax.name??"",$=b4(H,M,C),U=E.dom?.bbox??{x:0,y:0,w:0,h:0},B=E.dom?.type??null,j=null;E.ax.value!==void 0&&E.ax.value!==null&&(j=String(E.ax.value)),E.ax.checked!==void 0&&(j=String(E.ax.checked)),bR({role:H,kind:B})&&(j="[redacted]");let K={disabled:E.ax.disabled??!1};E.ax.checked!==void 0&&(K.checked=E.ax.checked===!0||E.ax.checked==="mixed"),E.ax.selected!==void 0&&(K.selected=E.ax.selected),E.ax.expanded!==void 0&&(K.expanded=E.ax.expanded);let Y;E.dom?.testId?Y=`[data-testid="${E.dom.testId}"]`:E.dom?.id&&(Y=`#${E.dom.id}`);let Ft={id:$,role:H,label:y4(M),kind:B,value:j,state:K,bbox:U};return Y!==void 0&&(Ft.selector=Y),Ft}),I="idle";try{let E=await t.evaluate(()=>document.readyState);E==="loading"?I="loading":E==="interactive"?I="navigating":I="idle"}catch{I="navigating"}I!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),b&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let P=w4(f),T=`obs_${e.observationCounter.toString(36)}`,R=new Date().toISOString();return{observationId:T,url:m,title:g,textSummary:P,interactive:_,status:{httpStatus:e.httpStatus??null,loadingState:I,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:R}}var OR,FR,LR=h(()=>{"use strict";$d();OR=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);FR="a[href], button, input, select, textarea, [role], [tabindex], label"});async function NR(t,e){try{let n=await t.nth(e).evaluate(i=>{let a=i,c=a.getAttribute("role")??a.tagName.toLowerCase(),l=a.getAttribute("aria-label")??a.getAttribute("placeholder")??(a.innerText!=null?a.innerText.trim().slice(0,200):"")??a.getAttribute("title")??"",d=a.getBoundingClientRect();return{role:c,label:l,x:Math.round(d.x),y:Math.round(d.y),w:Math.round(d.width),h:Math.round(d.height)}}),r=`${n.role}:${n.label}:${e}`,o=0;for(let i=0;i<r.length;i++)o=o*31+r.charCodeAt(i)>>>0;return{id:`el_${o.toString(16).padStart(6,"0").slice(0,6)}`,role:n.role,label:n.label,kind:null,value:null,state:{disabled:!1},bbox:{x:n.x,y:n.y,w:n.w,h:n.h}}}catch{return null}}async function my(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>NR(t,s)))).filter(o=>o!==null)}async function T4(t){let e=new Set,n=[];for(let{loc:r,count:o}of t)for(let s=0;s<o;s++){let i;try{i=await r.nth(s).evaluate(a=>{let c=a,l=c.getBoundingClientRect();return`${c.tagName}@${Math.round(l.x)},${Math.round(l.y)}`})}catch{continue}e.has(i)||(e.add(i),n.push({key:i,locator:r,index:s}))}return n}async function gy(t,e,n){switch(e.kind){case"element_id":return E4(t,e,n);case"selector":return _4(t,e);case"semantic":return x4(t,e)}}async function E4(t,e,n){let r=n.get(e.elementId);if(r===void 0)return{outcome:"not_found",query:e};if(r.selector!==void 0){let c=t.locator(r.selector);if(await c.count()===1)return{outcome:"resolved",locator:c}}let o=t.getByRole(r.role,{name:r.label,exact:!0}),s=await o.count();if(s===0)return{outcome:"not_found",query:e};if(s===1)return{outcome:"resolved",locator:o};let i=await my(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function _4(t,e){let n=t.locator(e.selector),r=await n.count();if(r===0)return{outcome:"not_found",query:e};if(r===1)return{outcome:"resolved",locator:n};let o=await my(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function x4(t,e){return e.role!==void 0?A4(t,e.text,e.role):R4(t,e.text,e)}async function A4(t,e,n){let r=t.getByRole(n,{name:e}),o=await r.count();if(o===0)return{outcome:"not_found",query:{kind:"semantic",text:e,role:n}};if(o===1)return{outcome:"resolved",locator:r};let s=await my(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function R4(t,e,n){let r=t.getByRole("button",{name:e}),o=t.getByRole("link",{name:e}),s=t.getByLabel(e,{exact:!1}),[i,a,c]=await Promise.all([r.count(),o.count(),s.count()]);if(i+a+c===0)return{outcome:"not_found",query:n};let d=[];i>0&&d.push({loc:r,count:i}),a>0&&d.push({loc:o,count:a}),c>0&&d.push({loc:s,count:c});let u=await T4(d);if(u.length===0)return{outcome:"not_found",query:n};if(u.length===1){let g=u[0];return g===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:g.locator.nth(g.index)}}let p=u.slice(0,5),f=[];for(let g=0;g<p.length;g++){let y=p[g];if(y===void 0)continue;let b=await NR(y.locator,y.index);if(b!==null){let w=`${b.role}:${b.label}:${g}`,v=0;for(let x=0;x<w.length;x++)v=v*31+w.charCodeAt(x)>>>0;f.push({...b,id:`el_${v.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var $R=h(()=>{"use strict"});async function hy(t,e,n,r){let o=t.url();if(o===n)return null;let s=It(o,e);if(s.allowed)return null;try{await t.goBack()}catch{await r()}return{outcome:"blocked_by_policy",url:o,reason:s.reason}}var UR=h(()=>{"use strict";Bn()});var by={};yo(by,{PlaywrightProvider:()=>yy});function BR(t){switch(t.kind){case"semantic":return t.role!==void 0?`semantic('${t.text}', role='${t.role}')`:`semantic('${t.text}')`;case"element_id":return`element_id(${t.elementId})`;case"selector":return`selector(${t.selector})`}}var yy,wy=h(()=>{"use strict";CR();LR();$R();Bn();UR();cy();yy=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new Hd(e)}async open(e){let n=It(e.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:e.url,reason:n.reason};let{sessionId:r}=e,o=await this.launcher.ensurePage(r),s=this.ensureSessionState(r),i=null,a=null;try{await o.goto(e.url,{timeout:e.timeoutMs??3e4,waitUntil:e.waitFor??"load"})}catch(u){a=u}let c=o.url();if(!(a!==null&&(c===""||c==="about:blank"))){let u=await hy(o,this.config,e.url,()=>this.close({sessionId:r}));if(u!==null)return u}(e.screenshot===!0||a!==null)&&(i=await this.captureScreenshot(o,r,"browser_open")),s.observationCounter+=1;let d=await Wd(o,{observationCounter:s.observationCounter,screenshotPath:i,consoleErrors:this.launcher.getConsoleErrorCount(r),httpStatus:this.launcher.getLastHttpStatus(r),hasDialog:this.launcher.hasOpenDialog(r)});if(this.updateSessionFromObservation(s,d.interactive,d.url,d.title,"browser_open"),a!==null)throw a;return d}async observe(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_observe: no page open for session ${n}`);let o=this.ensureSessionState(n),s=null;e.screenshot===!0&&(s=await this.captureScreenshot(r,n,"browser_observe")),o.observationCounter+=1;let i=await Wd(r,{observationCounter:o.observationCounter,screenshotPath:s,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n),includeHidden:e.includeHidden,maxElements:e.maxElements});return this.updateSessionFromObservation(o,i.interactive,i.url,i.title,"browser_observe"),i}async act(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_act: no page open for session ${n}`);let o=this.ensureSessionState(n),s=r.url(),i=e.timeoutMs??3e4,a=await gy(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${BR(e.target)}`);if(a.outcome==="ambiguous_target")return a;let{locator:c}=a,l=null,d=async()=>{switch(e.action){case"click":await c.click({timeout:i});break;case"fill":await c.fill(e.value??"");break;case"press":await c.press(e.value??"");break;case"select":await c.selectOption(e.value??"");break;case"hover":await c.hover({timeout:i});break;case"scroll_to":await c.scrollIntoViewIfNeeded({timeout:i});break;case"wait_for":await c.waitFor({timeout:i,state:"visible"});break}};try{await d()}catch(g){if(g instanceof Error&&/navigation|net::ERR/i.test(g.message))try{await d()}catch(y){l=y}else l=g}let u=await hy(r,this.config,s,()=>this.close({sessionId:n}));if(u!==null)return u;let p=null;(e.screenshot===!0||l!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await Wd(r,{observationCounter:o.observationCounter,screenshotPath:p,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),m=`browser_act:${e.action}`;if(this.updateSessionFromObservation(o,f.interactive,f.url,f.title,m),l!==null)throw l;return f}async render(e){return this.launcher.renderHtml(e.url,{timeoutMs:e.timeoutMs??3e4,waitUntil:e.waitFor??"load",signal:e.signal,requestGuard:e.requestGuard})}async screenshot(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_screenshot: no page open for session ${n}`);let o=this.ensureSessionState(n),s;if(e.target!==void 0){let d=await gy(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${BR(e.target)}`);if(d.outcome==="ambiguous_target")throw new Error("screenshot target ambiguous; specify element_id or selector");s=await d.locator.screenshot()}else s=await r.screenshot({fullPage:e.fullPage??!1});let{path:i,bytes:a}=await Yo(n,s,"browser_screenshot"),c=0,l=0;if(e.fullPage===!0)try{let d=await r.evaluate(()=>({w:document.documentElement.scrollWidth,h:document.documentElement.scrollHeight}));c=d.w,l=d.h}catch{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}else{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}return{path:i,bytes:a,width:c,height:l,dataBase64:s.toString("base64"),mediaType:"image/png"}}async extract(e){throw new Error("browser_extract not implemented in Phase 1")}async close(e){await this.launcher.closeSession(e.sessionId),this.sessions.delete(e.sessionId)}describe(e){let n=this.sessions.get(e);if(n===void 0)return null;let r=this.launcher.getPage(e);return{active:r!==void 0,url:n.currentUrl,title:n.currentTitle,lastAction:n.lastAction,lastActionAt:n.lastActionAt,openTabs:r!==void 0?1:0}}async shutdown(){this.sessions.clear(),await this.launcher.shutdown()}ensureSessionState(e){let n=this.sessions.get(e);if(n!==void 0)return n;let r={observationCounter:0,knownElements:new Map,lastAction:null,lastActionAt:null,currentUrl:null,currentTitle:null};return this.sessions.set(e,r),r}updateSessionFromObservation(e,n,r,o,s){e.knownElements=new Map(n.map(i=>[i.id,i])),e.currentUrl=r,e.currentTitle=o,e.lastAction=s,e.lastActionAt=new Date().toISOString()}async captureScreenshot(e,n,r){try{let o=await e.screenshot({fullPage:!1}),{path:s}=await Yo(n,o,r);return s}catch{return null}}}});var jr={};yo(jr,{__resetBrowserRegistryForTests:()=>D4,browserProviderActive:()=>C4,closeBrowserProvider:()=>ky,getBrowserProvider:()=>P4,getLastRoutingDecision:()=>O4,peekBrowserProvider:()=>M4});function jR(){Promise.resolve(ky()).then(()=>{process.exit(130)})}function HR(){Promise.resolve(ky()).then(()=>{process.exit(143)})}function WR(){Jt=null}function I4(){Kd||(process.on("SIGINT",jR),process.on("SIGTERM",HR),process.on("exit",WR),Kd=!0)}function KR(){Kd&&(process.removeListener("SIGINT",jR),process.removeListener("SIGTERM",HR),process.removeListener("exit",WR),Kd=!1)}async function P4(t){return Jt!==null?Jt:(Br!==null||(Br=(async()=>{let e=oy(t),n=t?.surface??(t?.env??{}).AGENT_SURFACE??k.AGENT_SURFACE,r=await hR({config:e,surface:n});Sy=r;let o;if(r.backend==="agent-browser"){let{AgentBrowserProvider:s}=await Promise.resolve().then(()=>(AR(),xR)),i=r.availability.connection;o=new s(e,i)}else{let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(wy(),by));o=new s(e)}return I4(),Jt=o,Br=null,o})()),Br)}async function ky(){if(Jt===null)return;let t=Jt;Jt=null,Br=null,KR(),await t.shutdown()}function C4(){return Jt!==null}function M4(){return Jt}function O4(){return Sy}function D4(){Jt=null,Br=null,Sy=null,KR()}var Jt,Br,Kd,Sy,Hr=h(()=>{"use strict";Bn();yR();F();Jt=null,Br=null,Kd=!1,Sy=null});async function GR(t,e){try{return await rR(t,e)}catch(n){return O("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function B4(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(Hr(),jr)),r=await n();try{return await r.render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}catch(o){if(r.name==="agent-browser"){let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(wy(),by)),{loadBrowserConfig:i}=await Promise.resolve().then(()=>(Bn(),sy)),a=i(),c=new s(a);try{return await c.render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}finally{await c.shutdown()}}throw o}}async function qR(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??B4,o=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},s=null,i="",a=t,c=null,l=null;try{let u=await Un(n,t,{headers:U4,signal:e.signal},o);c=u.status,a=u.url||t;let p=u.headers.get("content-type")??"";if(u.ok){if($4.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 u.text();if(N4.test(p)&&!L4.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await GR(f,a),e.signal.aborted)throw e.signal.reason??new Error("aborted")}}catch(u){if(e.signal.aborted||u instanceof Pe||u instanceof Error&&u.message.startsWith("web_scrape markdown mode received binary"))throw u;l=u}if(!(s===null||s.textLength<200)&&s!==null){let u=ey({html:i,extractedTextLength:s.textLength});return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1,...u!==void 0?{advisory:u}:{}}}try{await oa(t,o);let u=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:f=>oa(f,o)});u.finalUrl!==t&&/^https?:\/\//i.test(u.finalUrl)&&await oa(u.finalUrl,o);let p=await GR(u.html,u.finalUrl);if(e.signal.aborted)throw e.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=ey({html:u.html,extractedTextLength:p.textLength});return{title:p.title,markdown:p.markdown,finalUrl:u.finalUrl,usedRender:!0,...f!==void 0?{advisory:f}:{}}}}catch(u){if(e.signal.aborted||u instanceof Pe)throw u;if(s===null){let p=u instanceof Error?u.message:String(u),f=l instanceof Error?l.message:`HTTP ${c??"error"}`,m=new Error(`web_scrape could not retrieve ${t}: fetch failed (${f}) and render failed (${p}).`);throw m.cause=u,m}}if(s!==null)return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1};throw new Error(`web_scrape could not retrieve any content from ${t} (HTTP ${c??"error"}).`)}var L4,N4,$4,U4,XR=h(()=>{"use strict";oR();ty();$r();se();L4=/(text\/html|application\/xhtml\+xml)/i,N4=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,$4=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,U4={"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 W4(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(j4,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json","x-api-key":t.apiKey,"User-Agent":"agent-afk/web_scrape"},body:JSON.stringify({query:n,type:"auto",numResults:Math.min(Math.max(r,1),H4),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let c="";try{let d=await s.text(),u=Z(d);u&&(c=`: ${u.length>200?u.slice(0,200)+"\u2026":u}`)}catch{}let l=s.statusText?` ${s.statusText}`:"";throw new Error(`Exa Search HTTP ${s.status}${l}${c}`)}let i;try{i=await s.json()}catch(c){throw new Error(`Exa Search response was not JSON: ${c instanceof Error?c.message:String(c)}`)}return(i.results??[]).slice(0,r).map(c=>({title:(c.title??"").trim()||"(untitled)",url:c.url??"",description:(c.highlights?.[0]??"").trim()})).filter(c=>c.url.length>0)}}}function zR(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?W4({apiKey:t.exaApiKey,fetchFn:t.fetchFn}):{error:'web_scrape search mode requires a search backend. Set EXA_API_KEY (free tier at https://exa.ai) to enable it. Use mode: "markdown" to read a known URL, or mode: "raw" for a direct fetch.'}}function JR(t,e){if(e.length===0)return`# Search results for "${t}"
|
|
398
|
+
${gt(t,{headless:e,latched:n})}`,{cause:t})}var IR,l4,d4,RR,p4,fy=h(()=>{"use strict";IR=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],l4="pnpm exec playwright install chromium",d4=4;p4="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 Ur from"node:fs";import jd from"node:path";import{randomBytes as f4}from"node:crypto";function m4(){try{return"5.217.0"}catch{}try{let t=jd.resolve(import.meta.dirname,"../../../package.json"),e=Ur.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var g4,Hd,CR=h(()=>{"use strict";fy();L();se();g4=m4(),Hd=class{config;browser;sessions=new Map;launchPromise;launchFailure;shutdownComplete=!1;constructor(e){this.config=e}clearLaunchFailure(){this.launchFailure=void 0}latchLaunchFailure(e){this.launchFailure={error:e}}async ensureBrowser(){if(this.browser!==void 0&&this.browser.isConnected())return this.browser;if(this.launchFailure!==void 0)throw this.launchFailure.error;return this.browser!==void 0&&!this.browser.isConnected()&&(this.browser=void 0,this.launchPromise=void 0),this.launchPromise!==void 0?this.launchPromise:(this.launchPromise=(async()=>{let e;try{({chromium:e}=await import("playwright"))}catch(n){let r=Bd(n,this.config.headless,!0);throw this.latchLaunchFailure(r),this.launchPromise=void 0,r}try{let n=await e.launch({headless:this.config.headless});return this.browser=n,this.clearLaunchFailure(),n}catch(n){let r=Bd(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(e){let n=this.sessions.get(e);if(n!==void 0)return n.context;let r=await this.ensureBrowser(),o=this.loadStorageState(this.config.defaultProfile),s=await r.newContext({...this.contextOptions(),...o!==void 0?{storageState:o}:{}}),i={context:s,page:void 0,consoleErrors:0,lastHttpStatus:null,openDialog:void 0};return this.sessions.set(e,i),s}async ensurePage(e){let n=this.sessions.get(e);if(n!==void 0&&n.page!==void 0)return n.page;await this.ensureContext(e);let r=this.sessions.get(e);if(r===void 0)throw new Error(`[BrowserLauncher] session entry disappeared for sessionId=${e}`);if(r.page!==void 0)return r.page;let o=await r.context.newPage();return r.page=o,o.on("console",s=>{s.type()==="error"&&(r.consoleErrors+=1)}),o.on("request",s=>{s.isNavigationRequest()&&s.frame()===o.mainFrame()&&(r.lastHttpStatus=null)}),o.on("response",s=>{s.frame()===o.mainFrame()&&s.request().isNavigationRequest()&&(r.lastHttpStatus=s.status())}),o.on("dialog",s=>{r.openDialog=s}),o}getPage(e){return this.sessions.get(e)?.page}async renderHtml(e,n){let o=await(await this.ensureBrowser()).newContext(this.contextOptions()),s;n.requestGuard!==void 0&&await o.route("**/*",async a=>{try{await n.requestGuard(a.request().url()),await a.continue()}catch(c){s=c,await a.abort("blockedbyclient")}});let i=()=>{o.close().catch(()=>{})};if(n.signal?.aborted===!0)throw await o.close().catch(()=>{}),new Error("render aborted");n.signal!==void 0&&n.signal.addEventListener("abort",i,{once:!0});try{let a=await o.newPage(),c;try{c=await a.goto(e,{timeout:n.timeoutMs,waitUntil:n.waitUntil})}catch(p){throw s??p}if(s!==void 0)throw s;let l=await a.content();if(s!==void 0)throw s;let d=a.url(),u=c!==null?c.status():null;return{html:l,finalUrl:d,httpStatus:u}}finally{n.signal!==void 0&&n.signal.removeEventListener("abort",i),await o.close().catch(()=>{})}}getConsoleErrorCount(e){return this.sessions.get(e)?.consoleErrors??0}getLastHttpStatus(e){return this.sessions.get(e)?.lastHttpStatus??null}hasOpenDialog(e){return this.sessions.get(e)?.openDialog!==void 0}async dismissDialog(e,n=!0){let r=this.sessions.get(e);if(r===void 0||r.openDialog===void 0)return;let o=r.openDialog;r.openDialog=void 0,n?await o.accept():await o.dismiss()}async closeSession(e){this.clearLaunchFailure();let n=this.sessions.get(e);n!==void 0&&(this.sessions.delete(e),await this.saveStorageState(this.config.defaultProfile,n.context),n.page!==void 0&&await n.page.close().catch(()=>{}),await n.context.close().catch(()=>{}))}async shutdown(){if(this.clearLaunchFailure(),this.shutdownComplete)return;this.shutdownComplete=!0;let e=[...this.sessions.keys()];if(await Promise.all(e.map(n=>this.closeSession(n))),this.browser!==void 0){let n=this.browser;this.browser=void 0,await n.close().catch(()=>{})}}activeSessions(){return this.sessions.size}contextOptions(){return{viewport:{width:1280,height:800},userAgent:`Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 agent-afk/${g4}`}}loadStorageState(e){let n=Wm(e);try{if(!Ur.existsSync(n))return;let r=JSON.parse(Ur.readFileSync(n,"utf8"));return O("[browser/vault] restored session",{profile:e,file:n}),r}catch(r){O("[browser/vault] ignoring unreadable vault",{profile:e,file:n,err:r});return}}async saveStorageState(e,n){try{let r=Wm(e);if(!Ur.existsSync(r))return;let o=await n.storageState(),s=jd.join(jd.dirname(r),`.${jd.basename(r)}.${process.pid}.${f4(4).toString("hex")}.tmp`);Ur.writeFileSync(s,JSON.stringify(o),{mode:384}),Ur.chmodSync(s,384),Ur.renameSync(s,r),O("[browser/vault] saved session",{profile:e,file:r})}catch(r){O("[browser/vault] save failed",{profile:e,err:r})}}}});import{createHash as h4}from"node:crypto";function y4(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function b4(t,e,n){return`el_${h4("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function w4(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function MR(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function DR(t,e){let n=t.role??"",r=t.name??"";OR.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])DR(s,e)}async function S4(t){return t.evaluate(e=>{let n=Array.from(document.querySelectorAll(e)),r=[];for(let o of n){let s=o.getBoundingClientRect(),i=o;if(s.width===0&&s.height===0){let d=window.getComputedStyle(i);if(d.display==="none"||d.visibility==="hidden")continue}let a=o.tagName.toLowerCase(),c=o.getAttribute("aria-label")??o.getAttribute("placeholder")??(o.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a==="input"?o.type||null:o.getAttribute("type");r.push({name:c,tagName:a,type:l,id:o.id||null,testId:o.getAttribute("data-testid"),bbox:{x:Math.round(s.left),y:Math.round(s.top),w:Math.round(s.width),h:Math.round(s.height)}})}return r},FR).catch(()=>[])}async function k4(t){return t.evaluate(e=>{let n={button:"button",a:"link",input:"textbox",textarea:"textbox",select:"combobox"},r=Array.from(document.querySelectorAll(e)),o=[];for(let s of r){let i=s.tagName.toLowerCase(),a=s.getAttribute("role")??"",c=s.getAttribute("aria-label")??s.getAttribute("placeholder")??(s.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a||(n[i]??"");if(i==="input"){let g=s.type;g==="checkbox"?l="checkbox":g==="radio"?l="radio":g==="button"||g==="submit"||g==="reset"?l="button":g==="search"?l="searchbox":l="textbox"}if(!l)continue;let d="value"in s?s.value:void 0,u=d!==void 0?String(d):void 0,p=s.disabled??!1,f=i==="input"?s.checked:void 0,m={role:l,name:c,disabled:p};u!==void 0&&(m.value=u),f!==void 0&&(m.checked=f),o.push(m)}return o},FR).catch(()=>[])}function v4(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function Wd(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=v4(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=S4(t),c=t.evaluate(()=>document.body?.innerText??"").catch(()=>""),l=Promise.resolve(t.url()),d=t.title().catch(()=>""),[u,p,f,m,g]=await Promise.all([i,a,c,l,d]),y,b=!1;u!==null?(y=[],DR(u,y)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,y=(await k4(t)).filter(C=>OR.has(C.role??"")));let w=new Map;for(let E of p){let C=MR(E.name),H=w.get(C);(!H||H.bbox.w===0&&E.bbox.w>0)&&w.set(C,E)}let v=y.map(E=>({ax:E,dom:w.get(MR(E.name??""))})),x=r?v:v.filter(E=>E.dom?E.dom.bbox.w>0||E.dom.bbox.h>0:!0);x.sort((E,C)=>{let H=E.dom?.bbox.y??0,M=C.dom?.bbox.y??0;if(H!==M)return H-M;let $=E.dom?.bbox.x??0,U=C.dom?.bbox.x??0;return $-U}),x.length>200&&o.push("page has 200+ interactive elements; consider scoping");let _=x.slice(0,n).map((E,C)=>{let H=E.ax.role??"generic",M=E.ax.name??"",$=b4(H,M,C),U=E.dom?.bbox??{x:0,y:0,w:0,h:0},B=E.dom?.type??null,j=null;E.ax.value!==void 0&&E.ax.value!==null&&(j=String(E.ax.value)),E.ax.checked!==void 0&&(j=String(E.ax.checked)),bR({role:H,kind:B})&&(j="[redacted]");let K={disabled:E.ax.disabled??!1};E.ax.checked!==void 0&&(K.checked=E.ax.checked===!0||E.ax.checked==="mixed"),E.ax.selected!==void 0&&(K.selected=E.ax.selected),E.ax.expanded!==void 0&&(K.expanded=E.ax.expanded);let Y;E.dom?.testId?Y=`[data-testid="${E.dom.testId}"]`:E.dom?.id&&(Y=`#${E.dom.id}`);let Ft={id:$,role:H,label:y4(M),kind:B,value:j,state:K,bbox:U};return Y!==void 0&&(Ft.selector=Y),Ft}),I="idle";try{let E=await t.evaluate(()=>document.readyState);E==="loading"?I="loading":E==="interactive"?I="navigating":I="idle"}catch{I="navigating"}I!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),b&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let P=w4(f),T=`obs_${e.observationCounter.toString(36)}`,R=new Date().toISOString();return{observationId:T,url:m,title:g,textSummary:P,interactive:_,status:{httpStatus:e.httpStatus??null,loadingState:I,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:R}}var OR,FR,LR=h(()=>{"use strict";$d();OR=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);FR="a[href], button, input, select, textarea, [role], [tabindex], label"});async function NR(t,e){try{let n=await t.nth(e).evaluate(i=>{let a=i,c=a.getAttribute("role")??a.tagName.toLowerCase(),l=a.getAttribute("aria-label")??a.getAttribute("placeholder")??(a.innerText!=null?a.innerText.trim().slice(0,200):"")??a.getAttribute("title")??"",d=a.getBoundingClientRect();return{role:c,label:l,x:Math.round(d.x),y:Math.round(d.y),w:Math.round(d.width),h:Math.round(d.height)}}),r=`${n.role}:${n.label}:${e}`,o=0;for(let i=0;i<r.length;i++)o=o*31+r.charCodeAt(i)>>>0;return{id:`el_${o.toString(16).padStart(6,"0").slice(0,6)}`,role:n.role,label:n.label,kind:null,value:null,state:{disabled:!1},bbox:{x:n.x,y:n.y,w:n.w,h:n.h}}}catch{return null}}async function my(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>NR(t,s)))).filter(o=>o!==null)}async function T4(t){let e=new Set,n=[];for(let{loc:r,count:o}of t)for(let s=0;s<o;s++){let i;try{i=await r.nth(s).evaluate(a=>{let c=a,l=c.getBoundingClientRect();return`${c.tagName}@${Math.round(l.x)},${Math.round(l.y)}`})}catch{continue}e.has(i)||(e.add(i),n.push({key:i,locator:r,index:s}))}return n}async function gy(t,e,n){switch(e.kind){case"element_id":return E4(t,e,n);case"selector":return _4(t,e);case"semantic":return x4(t,e)}}async function E4(t,e,n){let r=n.get(e.elementId);if(r===void 0)return{outcome:"not_found",query:e};if(r.selector!==void 0){let c=t.locator(r.selector);if(await c.count()===1)return{outcome:"resolved",locator:c}}let o=t.getByRole(r.role,{name:r.label,exact:!0}),s=await o.count();if(s===0)return{outcome:"not_found",query:e};if(s===1)return{outcome:"resolved",locator:o};let i=await my(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function _4(t,e){let n=t.locator(e.selector),r=await n.count();if(r===0)return{outcome:"not_found",query:e};if(r===1)return{outcome:"resolved",locator:n};let o=await my(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function x4(t,e){return e.role!==void 0?A4(t,e.text,e.role):R4(t,e.text,e)}async function A4(t,e,n){let r=t.getByRole(n,{name:e}),o=await r.count();if(o===0)return{outcome:"not_found",query:{kind:"semantic",text:e,role:n}};if(o===1)return{outcome:"resolved",locator:r};let s=await my(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function R4(t,e,n){let r=t.getByRole("button",{name:e}),o=t.getByRole("link",{name:e}),s=t.getByLabel(e,{exact:!1}),[i,a,c]=await Promise.all([r.count(),o.count(),s.count()]);if(i+a+c===0)return{outcome:"not_found",query:n};let d=[];i>0&&d.push({loc:r,count:i}),a>0&&d.push({loc:o,count:a}),c>0&&d.push({loc:s,count:c});let u=await T4(d);if(u.length===0)return{outcome:"not_found",query:n};if(u.length===1){let g=u[0];return g===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:g.locator.nth(g.index)}}let p=u.slice(0,5),f=[];for(let g=0;g<p.length;g++){let y=p[g];if(y===void 0)continue;let b=await NR(y.locator,y.index);if(b!==null){let w=`${b.role}:${b.label}:${g}`,v=0;for(let x=0;x<w.length;x++)v=v*31+w.charCodeAt(x)>>>0;f.push({...b,id:`el_${v.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var $R=h(()=>{"use strict"});async function hy(t,e,n,r){let o=t.url();if(o===n)return null;let s=It(o,e);if(s.allowed)return null;try{await t.goBack()}catch{await r()}return{outcome:"blocked_by_policy",url:o,reason:s.reason}}var UR=h(()=>{"use strict";Bn()});var by={};yo(by,{PlaywrightProvider:()=>yy});function BR(t){switch(t.kind){case"semantic":return t.role!==void 0?`semantic('${t.text}', role='${t.role}')`:`semantic('${t.text}')`;case"element_id":return`element_id(${t.elementId})`;case"selector":return`selector(${t.selector})`}}var yy,wy=h(()=>{"use strict";CR();LR();$R();Bn();UR();cy();yy=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new Hd(e)}async open(e){let n=It(e.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:e.url,reason:n.reason};let{sessionId:r}=e,o=await this.launcher.ensurePage(r),s=this.ensureSessionState(r),i=null,a=null;try{await o.goto(e.url,{timeout:e.timeoutMs??3e4,waitUntil:e.waitFor??"load"})}catch(u){a=u}let c=o.url();if(!(a!==null&&(c===""||c==="about:blank"))){let u=await hy(o,this.config,e.url,()=>this.close({sessionId:r}));if(u!==null)return u}(e.screenshot===!0||a!==null)&&(i=await this.captureScreenshot(o,r,"browser_open")),s.observationCounter+=1;let d=await Wd(o,{observationCounter:s.observationCounter,screenshotPath:i,consoleErrors:this.launcher.getConsoleErrorCount(r),httpStatus:this.launcher.getLastHttpStatus(r),hasDialog:this.launcher.hasOpenDialog(r)});if(this.updateSessionFromObservation(s,d.interactive,d.url,d.title,"browser_open"),a!==null)throw a;return d}async observe(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_observe: no page open for session ${n}`);let o=this.ensureSessionState(n),s=null;e.screenshot===!0&&(s=await this.captureScreenshot(r,n,"browser_observe")),o.observationCounter+=1;let i=await Wd(r,{observationCounter:o.observationCounter,screenshotPath:s,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n),includeHidden:e.includeHidden,maxElements:e.maxElements});return this.updateSessionFromObservation(o,i.interactive,i.url,i.title,"browser_observe"),i}async act(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_act: no page open for session ${n}`);let o=this.ensureSessionState(n),s=r.url(),i=e.timeoutMs??3e4,a=await gy(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${BR(e.target)}`);if(a.outcome==="ambiguous_target")return a;let{locator:c}=a,l=null,d=async()=>{switch(e.action){case"click":await c.click({timeout:i});break;case"fill":await c.fill(e.value??"");break;case"press":await c.press(e.value??"");break;case"select":await c.selectOption(e.value??"");break;case"hover":await c.hover({timeout:i});break;case"scroll_to":await c.scrollIntoViewIfNeeded({timeout:i});break;case"wait_for":await c.waitFor({timeout:i,state:"visible"});break}};try{await d()}catch(g){if(g instanceof Error&&/navigation|net::ERR/i.test(g.message))try{await d()}catch(y){l=y}else l=g}let u=await hy(r,this.config,s,()=>this.close({sessionId:n}));if(u!==null)return u;let p=null;(e.screenshot===!0||l!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await Wd(r,{observationCounter:o.observationCounter,screenshotPath:p,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),m=`browser_act:${e.action}`;if(this.updateSessionFromObservation(o,f.interactive,f.url,f.title,m),l!==null)throw l;return f}async render(e){return this.launcher.renderHtml(e.url,{timeoutMs:e.timeoutMs??3e4,waitUntil:e.waitFor??"load",signal:e.signal,requestGuard:e.requestGuard})}async screenshot(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_screenshot: no page open for session ${n}`);let o=this.ensureSessionState(n),s;if(e.target!==void 0){let d=await gy(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${BR(e.target)}`);if(d.outcome==="ambiguous_target")throw new Error("screenshot target ambiguous; specify element_id or selector");s=await d.locator.screenshot()}else s=await r.screenshot({fullPage:e.fullPage??!1});let{path:i,bytes:a}=await Yo(n,s,"browser_screenshot"),c=0,l=0;if(e.fullPage===!0)try{let d=await r.evaluate(()=>({w:document.documentElement.scrollWidth,h:document.documentElement.scrollHeight}));c=d.w,l=d.h}catch{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}else{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}return{path:i,bytes:a,width:c,height:l,dataBase64:s.toString("base64"),mediaType:"image/png"}}async extract(e){throw new Error("browser_extract not implemented in Phase 1")}async close(e){await this.launcher.closeSession(e.sessionId),this.sessions.delete(e.sessionId)}describe(e){let n=this.sessions.get(e);if(n===void 0)return null;let r=this.launcher.getPage(e);return{active:r!==void 0,url:n.currentUrl,title:n.currentTitle,lastAction:n.lastAction,lastActionAt:n.lastActionAt,openTabs:r!==void 0?1:0}}async shutdown(){this.sessions.clear(),await this.launcher.shutdown()}ensureSessionState(e){let n=this.sessions.get(e);if(n!==void 0)return n;let r={observationCounter:0,knownElements:new Map,lastAction:null,lastActionAt:null,currentUrl:null,currentTitle:null};return this.sessions.set(e,r),r}updateSessionFromObservation(e,n,r,o,s){e.knownElements=new Map(n.map(i=>[i.id,i])),e.currentUrl=r,e.currentTitle=o,e.lastAction=s,e.lastActionAt=new Date().toISOString()}async captureScreenshot(e,n,r){try{let o=await e.screenshot({fullPage:!1}),{path:s}=await Yo(n,o,r);return s}catch{return null}}}});var jr={};yo(jr,{__resetBrowserRegistryForTests:()=>D4,browserProviderActive:()=>C4,closeBrowserProvider:()=>ky,getBrowserProvider:()=>P4,getLastRoutingDecision:()=>O4,peekBrowserProvider:()=>M4});function jR(){Promise.resolve(ky()).then(()=>{process.exit(130)})}function HR(){Promise.resolve(ky()).then(()=>{process.exit(143)})}function WR(){Jt=null}function I4(){Kd||(process.on("SIGINT",jR),process.on("SIGTERM",HR),process.on("exit",WR),Kd=!0)}function KR(){Kd&&(process.removeListener("SIGINT",jR),process.removeListener("SIGTERM",HR),process.removeListener("exit",WR),Kd=!1)}async function P4(t){return Jt!==null?Jt:(Br!==null||(Br=(async()=>{let e=oy(t),n=t?.surface??(t?.env??{}).AGENT_SURFACE??k.AGENT_SURFACE,r=await hR({config:e,surface:n});Sy=r;let o;if(r.backend==="agent-browser"){let{AgentBrowserProvider:s}=await Promise.resolve().then(()=>(AR(),xR)),i=r.availability.connection;o=new s(e,i)}else{let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(wy(),by));o=new s(e)}return I4(),Jt=o,Br=null,o})()),Br)}async function ky(){if(Jt===null)return;let t=Jt;Jt=null,Br=null,KR(),await t.shutdown()}function C4(){return Jt!==null}function M4(){return Jt}function O4(){return Sy}function D4(){Jt=null,Br=null,Sy=null,KR()}var Jt,Br,Kd,Sy,Hr=h(()=>{"use strict";Bn();yR();F();Jt=null,Br=null,Kd=!1,Sy=null});async function GR(t,e){try{return await rR(t,e)}catch(n){return O("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function B4(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(Hr(),jr)),r=await n();try{return await r.render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}catch(o){if(r.name==="agent-browser"){let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(wy(),by)),{loadBrowserConfig:i}=await Promise.resolve().then(()=>(Bn(),sy)),a=i(),c=new s(a);try{return await c.render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}finally{await c.shutdown()}}throw o}}async function qR(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??B4,o=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},s=null,i="",a=t,c=null,l=null;try{let u=await Un(n,t,{headers:U4,signal:e.signal},o);c=u.status,a=u.url||t;let p=u.headers.get("content-type")??"";if(u.ok){if($4.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 u.text();if(N4.test(p)&&!L4.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await GR(f,a),e.signal.aborted)throw e.signal.reason??new Error("aborted")}}catch(u){if(e.signal.aborted||u instanceof Pe||u instanceof Error&&u.message.startsWith("web_scrape markdown mode received binary"))throw u;l=u}if(!(s===null||s.textLength<200)&&s!==null){let u=ey({html:i,extractedTextLength:s.textLength});return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1,...u!==void 0?{advisory:u}:{}}}try{await oa(t,o);let u=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:f=>oa(f,o)});u.finalUrl!==t&&/^https?:\/\//i.test(u.finalUrl)&&await oa(u.finalUrl,o);let p=await GR(u.html,u.finalUrl);if(e.signal.aborted)throw e.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=ey({html:u.html,extractedTextLength:p.textLength});return{title:p.title,markdown:p.markdown,finalUrl:u.finalUrl,usedRender:!0,...f!==void 0?{advisory:f}:{}}}}catch(u){if(e.signal.aborted||u instanceof Pe)throw u;if(s===null){let p=u instanceof Error?u.message:String(u),f=l instanceof Error?l.message:`HTTP ${c??"error"}`,m=new Error(`web_scrape could not retrieve ${t}: fetch failed (${f}) and render failed (${p}).`);throw m.cause=u,m}}if(s!==null)return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1};throw new Error(`web_scrape could not retrieve any content from ${t} (HTTP ${c??"error"}).`)}var L4,N4,$4,U4,XR=h(()=>{"use strict";oR();ty();$r();se();L4=/(text\/html|application\/xhtml\+xml)/i,N4=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,$4=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,U4={"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 W4(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(j4,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json","x-api-key":t.apiKey,"User-Agent":"agent-afk/web_scrape"},body:JSON.stringify({query:n,type:"auto",numResults:Math.min(Math.max(r,1),H4),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let c="";try{let d=await s.text(),u=Z(d);u&&(c=`: ${u.length>200?u.slice(0,200)+"\u2026":u}`)}catch{}let l=s.statusText?` ${s.statusText}`:"";throw new Error(`Exa Search HTTP ${s.status}${l}${c}`)}let i;try{i=await s.json()}catch(c){throw new Error(`Exa Search response was not JSON: ${c instanceof Error?c.message:String(c)}`)}return(i.results??[]).slice(0,r).map(c=>({title:(c.title??"").trim()||"(untitled)",url:c.url??"",description:(c.highlights?.[0]??"").trim()})).filter(c=>c.url.length>0)}}}function zR(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?W4({apiKey:t.exaApiKey,fetchFn:t.fetchFn}):{error:'web_scrape search mode requires a search backend. Set EXA_API_KEY (free tier at https://exa.ai) to enable it. Use mode: "markdown" to read a known URL, or mode: "raw" for a direct fetch.'}}function JR(t,e){if(e.length===0)return`# Search results for "${t}"
|
|
399
399
|
|
|
400
400
|
(no results)`;let n=[`# Search results for "${t}"`,""];return e.forEach((r,o)=>{n.push(`## ${o+1}. ${r.title}`),r.url&&n.push(r.url),r.description&&n.push(r.description),n.push("")}),n.join(`
|
|
401
401
|
`).trimEnd()}var j4,H4,VR=h(()=>{"use strict";et();j4="https://api.exa.ai/search",H4=10});function Gd(t){if(t instanceof Error&&t.name==="TimeoutError")return"timeout";let e=t instanceof Error?t.message:String(t);return/Timeout\s+\d+\s*ms exceeded/i.test(e)?"timeout":void 0}var Wr=h(()=>{"use strict";fy()});function J4(t){if(!t||typeof t!="object")return{error:"Invalid input: expected an object"};let e=t,n=e.mode??"markdown";if(n!=="markdown"&&n!=="raw"&&n!=="search")return{error:`Invalid input: mode must be one of "markdown", "raw", "search" (got ${JSON.stringify(n)})`};let r=n,o,s;if(r==="search"){if(typeof e.query!="string"||e.query.length===0)return{error:'Invalid input: search mode requires a non-empty "query" string'};s=e.query}else{if(typeof e.url!="string"||e.url.length===0)return{error:`Invalid input: ${r} mode requires a non-empty "url" string`};let c;try{c=new URL(e.url)}catch{return{error:`Invalid input: "${e.url}" is not a valid absolute URL`}}if(c.protocol!=="http:"&&c.protocol!=="https:")return{error:`Invalid input: protocol "${c.protocol}" not supported (http/https only)`};o=c.toString()}let i=K4;if(e.timeout_ms!==void 0){if(typeof e.timeout_ms!="number"||!Number.isFinite(e.timeout_ms)||e.timeout_ms<=0)return{error:"Invalid input: timeout_ms must be a positive finite number"};i=Math.min(e.timeout_ms,G4)}let a=q4;if(e.max_bytes!==void 0){if(typeof e.max_bytes!="number"||!Number.isFinite(e.max_bytes)||e.max_bytes<=0)return{error:"Invalid input: max_bytes must be a positive finite number"};a=Math.min(e.max_bytes,X4)}return{mode:r,url:o,query:s,timeoutMs:i,maxBytes:a}}function vy(t,e){return Buffer.byteLength(t,"utf8")<=e?{content:t,truncated:!1}:{content:_t(t,e),truncated:!0}}function V4(t={}){let e=t.fetchFn??globalThis.fetch,n=t.env??process.env,r=t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{};return async(o,s)=>{if(typeof e!="function")return{content:"web_scrape unavailable: global fetch() is not present in this runtime (agent-afk requires Node 20+).",isError:!0};let i=J4(o);if("error"in i)return{content:i.error,isError:!0};if(s.aborted){let u=s.reason;return{content:`web_scrape aborted: ${u instanceof Error?u.message:String(u??"aborted")}`,isError:!0}}let a=new AbortController,c=()=>{a.abort(s.reason)},l,d=()=>{let u=a.signal.reason;return u instanceof Error?u.message:String(u??"aborted")};try{if(s.addEventListener("abort",c,{once:!0}),l=setTimeout(()=>{a.abort(new Error(`web_scrape timeout after ${i.timeoutMs}ms`))},i.timeoutMs),i.url!==void 0){let p=await Nr(i.url,r);if(a.signal.aborted)return{content:`web_scrape aborted: ${d()}`,isError:!0};if(!p.allowed)return{content:`web_scrape blocked: ${p.reason}`,isError:!0}}if(i.mode==="raw"){let p;try{let g={method:"GET",headers:{"User-Agent":"agent-afk/web_scrape",Accept:"*/*"},signal:a.signal};p=await Un(e,i.url,g,r)}catch(g){return a.signal.aborted?{content:`web_scrape aborted: ${d()}`,isError:!0}:g instanceof Pe?{content:`web_scrape blocked: ${g.message}`,isError:!0}:{content:`web_scrape network error: ${g instanceof Error?g.message:String(g)}`,isError:!0}}if(!p.ok)return{content:`web_scrape HTTP ${p.status} ${p.statusText||""}`.trimEnd()+` for ${i.url}`,isError:!0};let f;try{f=await p.text()}catch(g){return{content:`web_scrape read error: ${g instanceof Error?g.message:String(g)}`,isError:!0}}let m=vy(f,i.maxBytes);return{content:m.content,...m.truncated?{truncated:!0}:{}}}if(i.mode==="markdown")try{let p=await qR(i.url,{fetchFn:e,renderFn:t.renderFn,timeoutMs:i.timeoutMs,signal:a.signal,...t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{}});if(p.markdown.trim().length===0)return{content:`web_scrape extracted no readable content from ${i.url}.`,isError:!0};let f=vy(sR(p.markdown,p.advisory),i.maxBytes);return{content:f.content,...f.truncated?{truncated:!0}:{}}}catch(p){if(a.signal.aborted)return{content:`web_scrape aborted: ${d()}`,isError:!0};if(p instanceof Pe)return{content:`web_scrape blocked: ${p.message}`,isError:!0};let f=p instanceof Error?p.message:String(p),m=ze(p)&&!py(f)?` (the render fallback needs the optional Playwright browser \u2014 run \`${sa()}\`)`:"";return{content:`web_scrape markdown error: ${f}${m}`,isError:!0}}let u=zR({exaApiKey:n.EXA_API_KEY,fetchFn:e});if("error"in u)return{content:u.error,isError:!0};try{let p=await u.search(i.query,{limit:z4,timeoutMs:i.timeoutMs,signal:a.signal}),f=vy(JR(i.query,p),i.maxBytes);return{content:f.content,...f.truncated?{truncated:!0}:{}}}catch(p){return a.signal.aborted?{content:`web_scrape aborted: ${d()}`,isError:!0}:{content:`web_scrape search error (${u.name}): ${p instanceof Error?p.message:String(p)}`,isError:!0}}}finally{l!==void 0&&clearTimeout(l),s.removeEventListener("abort",c)}}}var K4,G4,q4,X4,z4,YR,QR=h(()=>{"use strict";XR();VR();$r();Wt();ty();Wr();K4=3e4,G4=12e4,q4=1e5,X4=1e6,z4=10;YR=V4()});function Z4(t){return Y4.has(t)?"low":t==="DELETE"?"high":"medium"}function eY(t){return Q4.has(t)}function rY(t){let e={};return t.forEach((n,r)=>{let o=r.toLowerCase();nY.has(o)||tY.some(s=>o.startsWith(s))||(e[r]=n)}),e}function oY(t,e){if(t==null)return{serialized:void 0,inferredContentType:void 0};let n=Object.keys(e).some(o=>o.toLowerCase()==="content-type");return typeof t=="string"?{serialized:t,inferredContentType:n?void 0:"text/plain"}:{serialized:JSON.stringify(t),inferredContentType:n?void 0:"application/json"}}function sY(t,e,n){let r=Buffer.byteLength(t,"utf8"),o=t,s=!1;if(r>n&&(o=_t(t,n),s=!0),!s&&/application\/json/i.test(e))try{return{body:JSON.parse(o),truncated:!1}}catch{}return{body:o,truncated:s}}async function tI(t){let{url:e,method:n,signal:r,domainCheck:o,recordEffect:s}=t,i=Math.min(t.maxResponseBytes??Ty,Ey),a={...t.headers},c=t.fetchFn??globalThis.fetch,l=t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{},d=Z4(n);if(o!==void 0){let T=o(e);if(!T.allowed)throw Object.assign(new Error(`web_request blocked by domain policy: ${T.reason}`),{name:"DomainPolicyError"})}let u=await Nr(e,l);if(!u.allowed)throw new Pe(u.reason);let{serialized:p,inferredContentType:f}=oY(t.body,a);f!==void 0&&(a["content-type"]=f);let m={method:n,headers:Object.keys(a).length>0?a:void 0,body:p,signal:r},y=eY(n)?{retries:2,baseDelayMs:300,maxDelayMs:5e3}:{retries:0},b=Date.now(),w;try{w=await Un(c,e,m,{...l,retry:y})}catch(T){throw T instanceof Pe,T}let v=Date.now()-b,x=w.headers.get("content-type")??"",A;try{let T=w.body?.getReader();if(!T)A="";else{let R=[],E=0,C=i*2;for(;;){let{done:H,value:M}=await T.read();if(H||!M)break;if(R.push(M),E+=M.byteLength,E>=C){await T.cancel();break}}A=new TextDecoder().decode(Buffer.concat(R,E))}}catch{A=""}let{body:_,truncated:I}=sY(A,x,i),P=rY(w.headers);return s!==void 0&&Promise.resolve(s({url:e,method:n,status:w.status,risk:d,timing_ms:v})).catch(()=>{}),{status:w.status,headers:P,body:_,truncated:I,timing_ms:v,risk:d}}function nI(t){if(typeof t!="string"||t.trim().length===0)return{error:"method must be a non-empty string (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS)"};let e=t.trim().toUpperCase(),n=["GET","POST","PUT","PATCH","DELETE","HEAD","OPTIONS"];return n.includes(e)?e:{error:`method "${t}" is not supported \u2014 must be one of: ${n.join(", ")}`}}var ZR,eI,Ty,Ey,Y4,Q4,tY,nY,rI=h(()=>{"use strict";$r();Wt();ZR=3e4,eI=12e4,Ty=1e5,Ey=1e6,Y4=new Set(["GET","HEAD","OPTIONS"]),Q4=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]);tY=["set-cookie","x-"],nY=new Set(["server","via","age","vary","authorization","www-authenticate"])});function iY(t){if(!t||typeof t!="object")return{error:"Invalid input: expected an object"};let e=t;if(typeof e.url!="string"||e.url.length===0)return{error:'Invalid input: "url" must be a non-empty string'};let n;try{n=new URL(e.url)}catch{return{error:`Invalid input: "${e.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=nI(e.method);if(typeof o=="object"&&"error"in o)return{error:`Invalid input: ${o.error}`};let s=o,i;if(e.body!==void 0&&e.body!==null){if(typeof e.body!="string"&&typeof e.body!="object")return{error:'Invalid input: "body" must be a string, object, or array'};i=e.body}let a={};if(e.headers!==void 0){if(typeof e.headers!="object"||e.headers===null||Array.isArray(e.headers))return{error:'Invalid input: "headers" must be a string-keyed object'};let u=e.headers;for(let[p,f]of Object.entries(u)){if(typeof f!="string")return{error:`Invalid input: header value for "${p}" must be a string`};a[p]=f}}let c=ZR;if(e.timeout_ms!==void 0){if(typeof e.timeout_ms!="number"||!Number.isFinite(e.timeout_ms)||e.timeout_ms<=0)return{error:'Invalid input: "timeout_ms" must be a positive finite number'};c=Math.min(e.timeout_ms,eI)}let l=Ty;if(e.max_response_bytes!==void 0){if(typeof e.max_response_bytes!="number"||!Number.isFinite(e.max_response_bytes)||e.max_response_bytes<=0)return{error:'Invalid input: "max_response_bytes" must be a positive finite number'};l=Math.min(e.max_response_bytes,Ey)}let d;if(e.credential!==void 0){if(typeof e.credential!="string"||e.credential.length===0)return{error:'Invalid input: "credential" must be a non-empty string (an env var name)'};d=e.credential}return{url:r,method:s,body:i,headers:a,timeoutMs:c,maxResponseBytes:l,credential:d}}function aY(t={}){let e=t.fetchFn??globalThis.fetch,n=t.env??process.env;async function r(){if(t.domainCheck!==void 0)return t.domainCheck;try{let{loadBrowserConfig:o,enforceDomainPolicy:s}=await Promise.resolve().then(()=>(Bn(),sy)),i=o();return a=>s(a,i)}catch{return}}return async(o,s)=>{if(typeof e!="function")return{content:"web_request unavailable: global fetch() is not present (agent-afk requires Node 20+).",isError:!0};let i=iY(o);if("error"in i)return{content:i.error,isError:!0};if(s.aborted){let p=s.reason;return{content:`web_request aborted: ${p instanceof Error?p.message:String(p??"aborted")}`,isError:!0}}let a={...i.headers};if(i.credential!==void 0){let p=n[i.credential];if(p===void 0||p.trim().length===0)return{content:`web_request credential error: environment variable "${i.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(m=>m.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 c=new AbortController,l=()=>c.abort(s.reason),d,u=()=>{let p=c.signal.reason;return p instanceof Error?p.message:String(p??"aborted")};try{s.addEventListener("abort",l,{once:!0}),d=setTimeout(()=>{c.abort(new Error(`web_request timeout after ${i.timeoutMs}ms`))},i.timeoutMs);let p=await r(),f={url:i.url,method:i.method,body:i.body,headers:a,maxResponseBytes:i.maxResponseBytes,signal:c.signal,fetchFn:e,lookupFn:t.lookupFn,domainCheck:p,recordEffect:t.recordEffect},m;try{m=await tI(f)}catch(w){if(c.signal.aborted)return{content:`web_request aborted: ${u()}`,isError:!0};if(w instanceof Pe)return{content:`web_request blocked: ${w.message}`,isError:!0};let v=w instanceof Error&&w.name==="DomainPolicyError"?"blocked":"network error",x=w instanceof Error?w.message:String(w);return{content:`web_request ${v}: ${x}`,isError:!0}}if(c.signal.aborted)return{content:`web_request aborted: ${u()}`,isError:!0};let g=m.body;if(typeof g=="string")g=Ge(g);else if(typeof g=="object"&&g!==null){let w=Ge(JSON.stringify(g));try{g=JSON.parse(w)}catch{g=w}}let y={status:m.status,headers:m.headers,body:g,timing_ms:m.timing_ms,...m.truncated?{truncated:!0}:{}};return{content:JSON.stringify(y,null,2),...m.truncated?{truncated:!0}:{}}}finally{d!==void 0&&clearTimeout(d),s.removeEventListener("abort",l)}}}var oI,sI=h(()=>{"use strict";rI();$r();_n();oI=aY()});import{existsSync as aI,mkdirSync as cY,readFileSync as lY,renameSync as dY,unlinkSync as uY,writeFileSync as pY}from"node:fs";import{dirname as iI,join as fY}from"node:path";import{randomBytes as mY}from"node:crypto";function Kr(t){let e=t??$m();if(!aI(e))return[];try{let n=lY(e,"utf-8");return JSON.parse(n)}catch(n){let r=n instanceof Error?n.message:String(n);return console.error(`[schedule-store] failed to parse ${e}: ${r}`),[]}}function ia(t,e){let n=e??$m();cY(iI(n),{recursive:!0});let r=fY(iI(n),`.schedules.json.${process.pid}.${mY(4).toString("hex")}.tmp`),o=JSON.stringify(t,null,2);try{pY(r,o,"utf-8"),dY(r,n)}catch(s){try{aI(r)&&uY(r)}catch{}throw s}}function cI(t,e){let n=Kr(e),r=n.map(c=>c.id),o=gY(t.name),s=hY(o,r),i=new Date().toISOString(),a={...t,notifyOn:t.notifyOn??"failure",id:s,createdAt:i,updatedAt:i};return n.push(a),ia(n,e),a}function lI(t,e){let n=Kr(e),r=n.length,o=n.filter(s=>s.id!==t);return o.length===r?!1:(ia(o,e),!0)}function dI(t,e){return Kr(e).find(n=>n.id===t)}function gY(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"")}function hY(t,e){if(!e.includes(t))return t;let n=2;for(;e.includes(`${t}-${n}`);)n+=1;return`${t}-${n}`}function uI(t){return{taskId:t.id,command:t.command,trigger:t.trigger??"cron",...t.cron!==void 0?{cronExpression:t.cron}:{},...t.notifyOn!==void 0?{notifyOn:t.notifyOn}:{},...t.notifyChat!==void 0?{notifyChat:t.notifyChat}:{}}}var pI=h(()=>{"use strict";L()});import{existsSync as yY,readFileSync as bY}from"node:fs";import{join as wY}from"node:path";async function Qo(t,e,n){let r,o;try{let s=wY(Hv("default"),"port");if(!yY(s))return{synced:!1,detail:"daemon-not-detected (no port file)"};let i=bY(s,"utf-8").trim(),a=SY(i);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 s=r.includes(":")?`[${r}]`:r,i=await fetch(`http://${s}:${o}${e}`,{method:t,headers:{"Content-Type":"application/json"},body:n!==void 0?JSON.stringify(n):void 0,signal:AbortSignal.timeout(2e3)});return i.ok?{synced:!0,detail:"synced"}:t==="POST"&&i.status===409?{synced:!0,detail:"already-registered"}:t==="DELETE"&&i.status===404?{synced:!0,detail:"not-registered"}:{synced:!1,detail:`daemon-rejected (HTTP ${i.status})`}}catch{return{synced:!1,detail:"daemon-unreachable (stale port file or network error)"}}}function SY(t){let e=parseInt(t,10);if(String(e)===t&&!Number.isNaN(e))return e<1||e>65535?null:{host:"localhost",port:e};let n=t.lastIndexOf(":");if(n<1)return null;let r=t.slice(0,n),o=t.slice(n+1);if(!/^\d+$/.test(o))return null;let s=parseInt(o,10);return Number.isNaN(s)||s<1||s>65535||/^:+$/.test(r)?null:{host:r.startsWith("[")&&r.endsWith("]")?r.slice(1,-1):r,port:s}}var _y,fI=h(()=>{"use strict";L();_y="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 kY}from"node:fs";import{readFile as vY}from"node:fs/promises";var mI,gI,hI,yI,bI=h(()=>{"use strict";pI();L();fI();mI=async(t,e)=>{if(!t||typeof t!="object")return{content:"Invalid input: expected object",isError:!0};let n=t;if(typeof n.name!="string"||!n.name)return{content:"Invalid input: name required",isError:!0};if(typeof n.command!="string"||!n.command)return{content:"Invalid input: command required",isError:!0};if(typeof n.cron!="string"||!n.cron)return{content:"Invalid input: cron required",isError:!0};let r=n.cron.trim().split(/\s+/);if(r.length!==5&&r.length!==6)return{content:"Invalid input: cron must be a 5 or 6-field expression",isError:!0};let o=n.notifyChat;if(o!==void 0&&typeof o!="number"&&typeof o!="string")return{content:"Invalid input: notifyChat must be a number (chat id) or string (chat id or alias name)",isError:!0};let s=cI({name:n.name,command:n.command,cron:n.cron,trigger:n.trigger??"cron",notifyOn:n.notifyOn,...o!==void 0?{notifyChat:o}:{},enabled:typeof n.enabled=="boolean"?n.enabled:!0}),i=s.enabled?await Qo("POST","/tasks",{taskId:s.id,command:s.command,cron:s.cron,trigger:s.trigger,notifyOn:s.notifyOn,...s.notifyChat!==void 0?{notifyChat:s.notifyChat}:{}}):await Qo("DELETE",`/tasks/${s.id}`);return{content:JSON.stringify({id:s.id,name:s.name,cron:s.cron,enabled:s.enabled,daemonSynced:i.synced,syncDetail:i.detail,...i.synced?{}:{syncNote:_y}})}},gI=async(t,e)=>{let n=Kr();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})))}},hI=async(t,e)=>{if(!t||typeof t!="object")return{content:"Invalid input: expected object",isError:!0};let n=t;if(typeof n.taskId!="string"||!n.taskId)return{content:"Invalid input: taskId required",isError:!0};let r=n.taskId,o=typeof n.limit=="number"?Math.min(Math.max(1,n.limit),50):10,s=Kc();if(!kY(s))return{content:JSON.stringify([])};let i;try{let l=await vY(s);i=(l.length>1048576?l.subarray(l.length-1048576):l).toString("utf-8")}catch{return{content:JSON.stringify([])}}let a=i.split(`
|
|
@@ -1901,7 +1901,7 @@ For \`contradicts\` / \`strengthens\` / \`weakens\`:
|
|
|
1901
1901
|
${e}`:`## Current SPINE.md
|
|
1902
1902
|
|
|
1903
1903
|
_(No SPINE.md exists yet \u2014 this may be the first session)_`;return["## Git Diff (this session)","","<git-diff>","```diff",bce(t),"```","</git-diff>","",n,"","Classify the architectural signals in this diff. Return ONLY the JSON array."].join(`
|
|
1904
|
-
`)}var Sce=new Set(["new-addition","strengthens","weakens","contradicts"]),kce=new Set(["INV","REJ","TST"]);function VW(t){let e=vce(t);if(!e)return{items:[],rawOutput:t,parsed:!1};let n;try{n=JSON.parse(e)}catch{return{items:[],rawOutput:t,parsed:!1}}if(!Array.isArray(n))return{items:[],rawOutput:t,parsed:!1};let r=[];for(let o of n){let s=Tce(o);s&&r.push(s)}return{items:r,rawOutput:t,parsed:!0}}function vce(t){let e=/```(?:json)?\s*([\s\S]*?)```/i.exec(t);if(e){let o=(e[1]??"").trim();if(o.startsWith("["))try{let s=JSON.parse(o);if(Array.isArray(s))return o}catch{}}let n=t.indexOf("[");if(n===-1)return null;let r=t.lastIndexOf("]");for(;r>n;){let o=t.slice(n,r+1);try{let s=JSON.parse(o);if(Array.isArray(s))return o}catch{}r=t.lastIndexOf("]",r-1)}return null}var ho=120,JW=500;function ei(t,e){return t.replace(/[\r\n]+/g," ").trim().slice(0,e)}function Tce(t){if(typeof t!="object"||t===null)return null;let e=t,n=e.label;if(typeof n!="string"||!Sce.has(n))return null;if(n==="new-addition"){let a=e.prefix,c=e.description,l=e.rationale;return typeof a!="string"||!kce.has(a)||typeof c!="string"||typeof l!="string"?null:{label:"new-addition",prefix:a,description:ei(c,ho),rationale:ei(l,JW)}}let r=e.existingId,o=e.existingDescription,s=e.description,i=e.rationale;return typeof r!="string"||typeof o!="string"||typeof s!="string"||typeof i!="string"?null:{label:n,existingId:ei(r,ho),existingDescription:ei(o,ho),description:ei(s,ho),rationale:ei(i,JW)}}F();$n();L();import{execFileSync as YW}from"node:child_process";import{appendFileSync as QW,mkdirSync as ZW}from"node:fs";import{join as e1}from"node:path";function bv(t={}){return async(e,n)=>{if(e.event!=="SessionEnd")return{};if(e.parentSessionId!==void 0)return{};if(k.AFK_DISABLE_SPINE_UPDATE==="1")return{};let r=e.sessionId??"unknown-session";try{let o=_ce(t.repoRoot??process.cwd()),s=xce(o);if(!s.trim())return{};let i=fv(o),a=i?Ace(i):"",c=await hv(s,a,n);if(!c.parsed||c.items.length===0)return{};let l=i??Rce(),d=!1,u=[],p=[];for(let f of c.items){if(f.label==="new-addition"){let m=new Date().toISOString().slice(0,10);gv(l,f.prefix,r,f.description,m),d=!0;continue}if(f.label==="strengthens"){let m=Em(l,f.existingId);if(m){let y=` (reinforced ${new Date().toISOString().slice(0,10)})
|
|
1904
|
+
`)}var Sce=new Set(["new-addition","strengthens","weakens","contradicts"]),kce=new Set(["INV","REJ","TST"]);function VW(t){let e=vce(t);if(!e)return{items:[],rawOutput:t,parsed:!1};let n;try{n=JSON.parse(e)}catch{return{items:[],rawOutput:t,parsed:!1}}if(!Array.isArray(n))return{items:[],rawOutput:t,parsed:!1};let r=[];for(let o of n){let s=Tce(o);s&&r.push(s)}return{items:r,rawOutput:t,parsed:!0}}function vce(t){let e=/```(?:json)?\s*([\s\S]*?)```/i.exec(t);if(e){let o=(e[1]??"").trim();if(o.startsWith("["))try{let s=JSON.parse(o);if(Array.isArray(s))return o}catch{}}let n=t.indexOf("[");if(n===-1)return null;let r=t.lastIndexOf("]");for(;r>n;){let o=t.slice(n,r+1);try{let s=JSON.parse(o);if(Array.isArray(s))return o}catch{}r=t.lastIndexOf("]",r-1)}return null}var ho=120,JW=500;function ei(t,e){return t.replace(/[\r\n]+/g," ").trim().slice(0,e)}function Tce(t){if(typeof t!="object"||t===null)return null;let e=t,n=e.label;if(typeof n!="string"||!Sce.has(n))return null;if(n==="new-addition"){let a=e.prefix,c=e.description,l=e.rationale;return typeof a!="string"||!kce.has(a)||typeof c!="string"||typeof l!="string"?null:{label:"new-addition",prefix:a,description:ei(c,ho),rationale:ei(l,JW)}}let r=e.existingId,o=e.existingDescription,s=e.description,i=e.rationale;return typeof r!="string"||typeof o!="string"||typeof s!="string"||typeof i!="string"?null:{label:n,existingId:ei(r,ho),existingDescription:ei(o,ho),description:ei(s,ho),rationale:ei(i,JW)}}F();$n();L();import{execFileSync as YW}from"node:child_process";import{appendFileSync as QW,mkdirSync as ZW}from"node:fs";import{join as e1}from"node:path";function bv(t={}){return async(e,n)=>{if(e.event!=="SessionEnd")return{};if(e.parentSessionId!==void 0)return{};if(k.AFK_DISABLE_SPINE_UPDATE==="1")return{};let r=e.sessionId??"unknown-session";try{let o=_ce(t.repoRoot??process.cwd()),s=xce(o);if(!s.trim())return{};let i=fv(o),a=i?Ace(i):"",c=await hv(s,a,n);if(!c.parsed||c.items.length===0)return{};let l=i??Rce(),d=!1,u=[],p=[];for(let f of c.items){if(f.label==="new-addition"){let m=new Date().toISOString().slice(0,10);gv(l,f.prefix,r,f.description,m),d=!0;continue}if(f.label==="strengthens"){let m=Em(l,f.existingId);if(m){let y=` (reinforced ${new Date().toISOString().slice(0,10)})`,b=(m.description.replace(/ \(reinforced \d{4}-\d{2}-\d{2}\)?$/,"")+y).slice(0,ho);b!==m.description&&(m.description=b,d=!0)}else yv({type:"strengthens-unresolved",sessionId:r,item:f,ts:new Date().toISOString()});continue}if(f.label==="weakens"){let m=Em(l,f.existingId);if(m){let y=` (partially weakened ${new Date().toISOString().slice(0,10)})`,b=(m.description.replace(/ \(partially weakened \d{4}-\d{2}-\d{2}\)?$/,"")+y).slice(0,ho);b!==m.description&&(m.description=b,d=!0),p.push({type:"weakens",sessionId:r,item:f,ts:new Date().toISOString()})}else p.push({type:"weakens-unresolved",sessionId:r,item:f,ts:new Date().toISOString()});continue}f.label==="contradicts"&&u.push(f)}d&&mv(o,l);for(let f of p)yv(f);for(let f of u)Ece(f,r)}catch(o){try{let s=Q();ZW(s,{recursive:!0}),QW(e1(s,"spine-pending.jsonl"),JSON.stringify({type:"hook-error",sessionId:r,error:o instanceof Error?o.message:String(o),ts:new Date().toISOString()})+`
|
|
1905
1905
|
`,"utf-8")}catch{}}return{}}}function Ece(t,e){yv({type:"contradicts",sessionId:e,item:t,ts:new Date().toISOString()}),zt(`\u26A0\uFE0F SPINE conflict needs review:
|
|
1906
1906
|
${t.existingId.slice(0,200)}: ${t.existingDescription.slice(0,200)}
|
|
1907
1907
|
Conflict: ${t.description.slice(0,200)}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-afk",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.217.0",
|
|
4
4
|
"description": "Open-source coding-agent harness you can actually change — own the loop (prompts, gates, routing, skills, terminal states), use any model, run long tasks while you're away.",
|
|
5
5
|
"main": "dist/index.mjs",
|
|
6
6
|
"types": "dist/index.d.ts",
|