@duckmind/dm-darwin-arm64 0.52.3 → 0.53.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dm +0 -0
  2. package/extensions/.dm-extensions.json +15 -8
  3. package/extensions/dm-cua/bin/browser-cua.mjs +6 -6
  4. package/extensions/dm-cua/index.js +5 -5
  5. package/extensions/dm-cua/src/browser-cua-lib.mjs +2 -2
  6. package/extensions/greedysearch-dm/bin/cdp-greedy.mjs +8 -1
  7. package/extensions/greedysearch-dm/bin/cdp-headless.mjs +1 -1
  8. package/extensions/greedysearch-dm/bin/cdp-visible.mjs +1 -1
  9. package/extensions/greedysearch-dm/bin/cdp.mjs +29 -20
  10. package/extensions/greedysearch-dm/bin/gschrome.mjs +1 -10
  11. package/extensions/greedysearch-dm/bin/kill-visible.mjs +1 -1
  12. package/extensions/greedysearch-dm/bin/launch-visible.mjs +1 -4
  13. package/extensions/greedysearch-dm/bin/launch.mjs +9 -5
  14. package/extensions/greedysearch-dm/bin/mcp.mjs +375 -0
  15. package/extensions/greedysearch-dm/bin/search.mjs +310 -156
  16. package/extensions/greedysearch-dm/bin/visible.mjs +1 -1
  17. package/extensions/greedysearch-dm/extractors/bing-copilot.mjs +205 -68
  18. package/extensions/greedysearch-dm/extractors/chatgpt.mjs +229 -140
  19. package/extensions/greedysearch-dm/extractors/common.mjs +160 -50
  20. package/extensions/greedysearch-dm/extractors/consensus.mjs +225 -92
  21. package/extensions/greedysearch-dm/extractors/consent.mjs +44 -17
  22. package/extensions/greedysearch-dm/extractors/gemini.mjs +275 -136
  23. package/extensions/greedysearch-dm/extractors/google-ai.mjs +172 -64
  24. package/extensions/greedysearch-dm/extractors/logically.mjs +183 -69
  25. package/extensions/greedysearch-dm/extractors/perplexity.mjs +331 -65
  26. package/extensions/greedysearch-dm/extractors/semantic-scholar.mjs +118 -41
  27. package/extensions/greedysearch-dm/index.js +20 -17
  28. package/extensions/greedysearch-dm/package.json +8 -3
  29. package/extensions/greedysearch-dm/skills/greedy-search/skill.md +8 -8
  30. package/extensions/greedysearch-dm/src/fetcher.mjs +2 -2
  31. package/extensions/greedysearch-dm/src/formatters/results.js +8 -6
  32. package/extensions/greedysearch-dm/src/github.mjs +7 -7
  33. package/extensions/greedysearch-dm/src/reddit.mjs +1 -1
  34. package/extensions/greedysearch-dm/src/search/browser-lifecycle.mjs +10 -9
  35. package/extensions/greedysearch-dm/src/search/challenge-detect.mjs +48 -0
  36. package/extensions/greedysearch-dm/src/search/chrome.mjs +129 -53
  37. package/extensions/greedysearch-dm/src/search/constants.mjs +8 -8
  38. package/extensions/greedysearch-dm/src/search/engines.mjs +9 -9
  39. package/extensions/greedysearch-dm/src/search/fetch-source.mjs +154 -77
  40. package/extensions/greedysearch-dm/src/search/minimize.mjs +1 -0
  41. package/extensions/greedysearch-dm/src/search/paths.mjs +1 -1
  42. package/extensions/greedysearch-dm/src/search/pdf.mjs +1 -1
  43. package/extensions/greedysearch-dm/src/search/port-pid.mjs +1 -0
  44. package/extensions/greedysearch-dm/src/search/progress.mjs +2 -0
  45. package/extensions/greedysearch-dm/src/search/recovery.mjs +1 -1
  46. package/extensions/greedysearch-dm/src/search/research.mjs +262 -167
  47. package/extensions/greedysearch-dm/src/search/scale-aware.mjs +11 -0
  48. package/extensions/greedysearch-dm/src/search/simple-research.mjs +827 -0
  49. package/extensions/greedysearch-dm/src/search/synthesis-runner.mjs +11 -11
  50. package/extensions/greedysearch-dm/src/search/synthesis.mjs +11 -11
  51. package/extensions/greedysearch-dm/src/tools/greedy-search-handler.js +23 -20
  52. package/extensions/greedysearch-dm/src/tools/shared.js +10 -9
  53. package/extensions/greedysearch-dm/src/utils/node-runtime.mjs +1 -1
  54. package/package.json +1 -1
  55. package/extensions/greedysearch-dm/src/search/cdp-endpoint.mjs +0 -3
  56. package/extensions/greedysearch-dm/src/utils/browser-executable.mjs +0 -1
@@ -1,46 +1,54 @@
1
- import{createRequire as Gr}from"node:module";var Hr=Object.defineProperty;var Fr=(t)=>t;function Yr(t,e){this[t]=Fr.bind(null,e)}var et=(t,e)=>{for(var r in e)Hr(t,r,{get:e[r],enumerable:!0,configurable:!0,set:Yr.bind(e,r)})};var gt=(t,e)=>()=>(t&&(e=t(t=0)),e);var Vr=Gr(import.meta.url);var lr={};et(lr,{fetchTopSource:()=>ma,fetchSourceContent:()=>ar,fetchMultipleSources:()=>ca});import{createRequire as $n}from"node:module";import{Readability as cn}from"@mozilla/readability";import{JSDOM as mn}from"jsdom";import bn from"turndown";import{platform as hi,tmpdir as An}from"node:os";import{spawn as Rn}from"node:child_process";import{dirname as Jn,join as dn}from"node:path";import{fileURLToPath as Hn}from"node:url";import{basename as Fn}from"node:path";import{existsSync as mt,mkdirSync as Yn,readFileSync as Ke,writeFileSync as Gn}from"node:fs";import{homedir as Vn}from"node:os";import{join as Ue}from"node:path";import{tmpdir as _t}from"node:os";import{platform as vi,tmpdir as Zn}from"node:os";import{existsSync as bt,mkdirSync as Bn,readFileSync as Ie,writeFileSync as Kn}from"node:fs";import{homedir as Un}from"node:os";import{join as Xe}from"node:path";import{tmpdir as kt}from"node:os";import{existsSync as yt,mkdirSync as ra,readFileSync as qe,writeFileSync as na}from"node:fs";import{homedir as aa}from"node:os";import{join as tr}from"node:path";import{tmpdir as st}from"node:os";function _n(t={}){return{...He,...t}}function Fe(t){try{let e=new URL(t),r=e.hostname.toLowerCase();for(let n of yn)if(n.test(r))return{blocked:!0,reason:`Private/internal address: ${r}`};if(e.protocol==="file:")return{blocked:!0,reason:"File protocol not allowed"};return{blocked:!1}}catch(e){return{blocked:!0,reason:`Invalid URL: ${e.message}`}}}function kn(t){try{let e=new URL(t);if(!(e.hostname==="github.com"||e.hostname.endsWith(".github.com")))return t;let r=e.pathname.split("/").filter(Boolean);if(r.length<5)return t;let[n,a,l,i,...f]=r;if(l!=="blob")return t;let o=f.join("/");return`https://raw.githubusercontent.com/${n}/${a}/${i}/${o}`}catch{return t}}async function sn(t,e={}){let r=Fe(t);if(r.blocked)return{ok:!1,url:t,finalUrl:t,status:403,error:`Blocked: ${r.reason}`,needsBrowser:!1};let n=t;if(t=kn(t),t!==n)console.error(`[fetcher] Rewrote GitHub URL: ${n.slice(0,60)}... → raw.githubusercontent.com`);let{timeoutMs:a=15000,userAgent:l,signal:i}=e,f=new AbortController,o=setTimeout(()=>f.abort(),a);if(i)i.addEventListener("abort",()=>f.abort(),{once:!0});try{let g=await fetch(t,{method:"GET",headers:{...He,"user-agent":l||de},redirect:"follow",signal:f.signal});clearTimeout(o);let p=g.headers.get("content-type")||"",h=g.url,m=g.headers.get("last-modified")||"",c=!1;try{c=new URL(h).hostname.toLowerCase()==="raw.githubusercontent.com"}catch{}if(p.includes("text/plain")&&c){let C=await g.text();return{ok:!0,url:n,finalUrl:h,status:g.status,title:h.split("/").pop()||"GitHub File",byline:"",siteName:"GitHub",lang:"",publishedTime:m,lastModified:m,markdown:C,contentLength:C.length,excerpt:C.slice(0,300).replaceAll(/\n/g," "),needsBrowser:!1}}if(!p.includes("text/html")&&!p.includes("application/xhtml"))return{ok:!1,url:t,finalUrl:h,status:g.status,error:`Unsupported content type: ${p}`,needsBrowser:!1};let y=await g.text(),b=Ye(g.status,y,h,t);if(b.blocked)return{ok:!1,url:t,finalUrl:h,status:g.status,error:`Blocked: ${b.reason}`,needsBrowser:!0};let w=Ge(y,h),k=Ve(w);if(!k.ok)return{ok:!1,url:t,finalUrl:h,status:g.status,error:`Low quality content: ${k.reason}`,needsBrowser:!0};return{ok:!0,url:t,finalUrl:h,status:g.status,title:w.title,byline:w.byline,siteName:w.siteName,lang:w.lang,publishedTime:w.publishedTime||m,lastModified:m,markdown:w.markdown,excerpt:w.excerpt,contentLength:w.markdown.length,needsBrowser:!1}}catch(g){clearTimeout(o);let p=Cn(g);return{ok:!1,url:t,finalUrl:t,status:0,error:g.message,needsBrowser:p}}}function Ye(t,e,r,n){let a=e.match(/<title[^>]*>([^<]*)<\/title>/i)?.[1]?.toLowerCase()||"",l=e.slice(0,30000).toLowerCase(),i=`${a} ${l}`;if(t===403||t===429||t===503)return{blocked:!0,reason:`HTTP ${t}`};let f=[{pattern:/class=["'][^"']*captcha["']|<div[^>]*id=["']captcha/i,reason:"captcha"},{pattern:/g-recaptcha|data-sitekey|i['"]m not a robot/i,reason:"captcha"},{pattern:/checking your browser.{0,100}please wait|cf-browser-verification/i,reason:"cloudflare challenge"},{pattern:/just a moment.{0,50}security check|ddos protection by cloudflare/i,reason:"cloudflare challenge"},{pattern:/unusual traffic.{0,50}from your computer network/i,reason:"unusual traffic"},{pattern:/bot detected|automated.{0,20}request/i,reason:"bot detection"},{pattern:/enable\s+javascript\s+to\s+view|javascript\s+is\s+required.{0,50}enabled/i,reason:"requires javascript"},{pattern:/access denied|accessdenied/i,reason:"access denied"},{pattern:/protected by anubis|anubis uses a proof-of-work/i,reason:"anubis challenge"}];for(let g of f)if(g.pattern.test(i))return{blocked:!0,reason:g.reason};let o=En(n,r,e);if(o)return{blocked:!0,reason:o};return{blocked:!1}}function En(t,e,r){try{let n=new URL(t),a=new URL(e);if(n.hostname.toLowerCase()===a.hostname.toLowerCase())return;let l=a.hostname.toLowerCase();if(vn.some((f)=>l===f||l.endsWith(`.${f}`)))return`redirected to login (${a.hostname})`;if(jn.some((f)=>l.startsWith(f)))return`redirected to login (${a.hostname})`;let i=r.slice(0,20000).toLowerCase();if(Dn.some((f)=>i.includes(f)))return`redirected to login page (${a.hostname})`}catch{}return}function Cn(t){let e=t.message.toLowerCase();return e.includes("fetch failed")||e.includes("unable to verify")||e.includes("certificate")||e.includes("timeout")}function Te(t){let e=['meta[property="article:published_time"]','meta[name="article:published_time"]','meta[property="og:published_time"]','meta[name="publication_date"]','meta[name="date"]','meta[itemprop="datePublished"]','time[itemprop="datePublished"]','meta[name="DC.date"]'];for(let r of e){let n=t.querySelector(r),a=n?.getAttribute("content")||n?.getAttribute("datetime")||"";if(a)return a}return""}function Ge(t,e){let r=new mn(t,{url:e}).window.document,n=new cn(r).parse();if(n&&n.content){let l=Je.turndown(n.content).replaceAll(/\n{3,}/g,`
1
+ import{createRequire as rp}from"node:module";var pp=Object.defineProperty;var gp=(t)=>t;function ap(t,n){this[t]=gp.bind(null,n)}var dt=(t,n)=>{for(var f in n)pp(t,f,{get:n[f],enumerable:!0,configurable:!0,set:ap.bind(n,f)})};var qt=(t,n)=>()=>(t&&(n=t(t=0)),n);var Mt=rp(import.meta.url);var af={};dt(af,{writeSourcesToFiles:()=>Vt});import{mkdirSync as Wp,writeFileSync as Vp}from"node:fs";import{join as gf}from"node:path";function Vt(t,n=mp){return Wp(n,{recursive:!0}),t.map((f)=>{if(!f.content||f.content.length<10)return f;let p=String(f.id||"unknown").replace(/[^a-zA-Z0-9_-]/g,""),g=(f.canonicalUrl||f.url||"").replace(/^https?:\/\//,"").replace(/[^a-zA-Z0-9]/g,"-").slice(0,40),r=`${p}-${g}.md`,a=gf(n,r),l=`---
2
+ url: ${f.finalUrl||f.url}
3
+ title: ${f.title||""}
4
+ source: ${f.source||"unknown"}
5
+ status: ${f.status||""}
6
+ chars: ${f.contentChars||f.content.length}
7
+ ---
8
+
9
+ `;Vp(a,l+f.content,"utf8");let{content:w,...$}=f;return{...$,contentPath:a,contentChars:f.contentChars||w.length}})}var mp;var an=qt(()=>{mp=gf(process.cwd(),".dm","greedysearch-sources")});var Nn={};dt(Nn,{fetchTopSource:()=>qg,fetchSourceContent:()=>Wf,fetchMultipleSources:()=>On});import{createRequire as Jp}from"node:module";import{createRequire as Zp}from"node:module";import{spawn as lg}from"node:child_process";import{basename as wg}from"node:path";import{dirname as $g,join as _g}from"node:path";import{fileURLToPath as hg}from"node:url";import{existsSync as Jt,mkdirSync as eg,readFileSync as Af,writeFileSync as Eg}from"node:fs";import{homedir as Dg}from"node:os";import{join as Tf}from"node:path";import{tmpdir as bg}from"node:os";import{existsSync as Zt,mkdirSync as Cg,readFileSync as kf,writeFileSync as vg}from"node:fs";import{homedir as jg}from"node:os";import{join as Hf}from"node:path";import{tmpdir as Pg}from"node:os";import{existsSync as Kt,mkdirSync as Vg,readFileSync as If,writeFileSync as mg}from"node:fs";import{homedir as Jg}from"node:os";import{join as Mf}from"node:path";import{tmpdir as Zg}from"node:os";async function Kp(){if(mt)return mt;let[{Readability:t},{JSDOM:n},{default:f}]=await Promise.all([import("@mozilla/readability"),import("jsdom"),import("turndown")]),p=new f({headingStyle:"atx",bulletListMarker:"-",codeBlockStyle:"fenced"});return p.addRule("removeDataUrls",{filter:(g)=>g.tagName==="IMG"&&g.getAttribute("src")?.startsWith("data:"),replacement:()=>""}),mt={Readability:t,JSDOM:n,turndown:p},mt}function Up(t){if(!t||t.includes(":"))return null;let n=t.split(".");if(n.length<1||n.length>4)return null;if(!n.every((g)=>Bp.test(g)))return null;let f=n.map((g)=>{if(/^0x/i.test(g))return parseInt(g,16);if(/^0[0-7]+$/.test(g))return parseInt(g,8);return parseInt(g,10)});if(f.some((g)=>!Number.isFinite(g)||g<0))return null;let p;if(f.length===1){if(f[0]>4294967295)return null;p=[f[0]>>>24&255,f[0]>>>16&255,f[0]>>>8&255,f[0]&255]}else if(f.length===2){if(f[0]>255||f[1]>16777215)return null;p=[f[0],f[1]>>>16&255,f[1]>>>8&255,f[1]&255]}else if(f.length===3){if(f[0]>255||f[1]>255||f[2]>65535)return null;p=[f[0],f[1],f[2]>>>8&255,f[2]&255]}else{if(f.some((g)=>g>255))return null;p=f}return p.join(".")}function Qp(t){let n=t.match(Xp);if(n)return`${n[1]}.${n[2]}.${n[3]}.${n[4]}`;let f=t.match(op);if(f){let p=parseInt(f[1],16),g=parseInt(f[2],16);if(p>65535||g>65535)return null;return[p>>>8&255,p&255,g>>>8&255,g&255].join(".")}return null}function rf(t){return jf.some((n)=>n.test(t))}function xp(t={}){return{...vf,...t}}function $n(t){try{if(typeof t!=="string"||!t.trim())return{blocked:!0,reason:"URL must be a non-empty string"};let n=new URL(t);if(n.protocol!=="http:"&&n.protocol!=="https:")return{blocked:!0,reason:`Protocol not allowed: ${n.protocol}`};let f=n.hostname.toLowerCase();for(let g of jf)if(g.test(f))return{blocked:!0,reason:`Private/internal address: ${f}`};if(f.startsWith("[")&&f.endsWith("]")){let g=f.slice(1,-1),r=Qp(g);if(r&&rf(r))return{blocked:!0,reason:`Private/internal address: ${f} (maps to ${r})`}}let p=Up(f);if(p&&rf(p))return{blocked:!0,reason:`Private/internal address: ${f} (normalizes to ${p})`};return{blocked:!1}}catch(n){return{blocked:!0,reason:`Invalid URL: ${n.message}`}}}function zp(t){try{let n=new URL(t);if(!(n.hostname==="github.com"||n.hostname.endsWith(".github.com")))return t;let f=n.pathname.split("/").filter(Boolean);if(f.length<5)return t;let[p,g,r,a,...l]=f;if(r!=="blob")return t;let w=l.join("/");return`https://raw.githubusercontent.com/${p}/${g}/${a}/${w}`}catch{return t}}async function Sp(t,n={}){let f=$n(t);if(f.blocked)return{ok:!1,url:t,finalUrl:t,status:403,error:`Blocked: ${f.reason}`,needsBrowser:!1};let p=t;if(t=zp(t),t!==p)console.error(`[fetcher] Rewrote GitHub URL: ${p.slice(0,60)}... → raw.githubusercontent.com`);let{timeoutMs:g=15000,userAgent:r,signal:a}=n,l=new AbortController,w=setTimeout(()=>l.abort(),g);if(a)a.addEventListener("abort",()=>l.abort(),{once:!0});try{let $=await fetch(t,{method:"GET",headers:{...vf,"user-agent":r||Cf},redirect:"follow",signal:l.signal});clearTimeout(w);let _=$.headers.get("content-type")||"",e=$.url,E=$.headers.get("last-modified")||"",h=$n(e);if(h.blocked)return{ok:!1,url:t,finalUrl:e,status:$.status,error:`Blocked: ${h.reason}`,needsBrowser:!1};let b=!1;try{b=new URL(e).hostname.toLowerCase()==="raw.githubusercontent.com"}catch{}if(_.includes("text/plain")&&b){let y=await $.text();return{ok:!0,url:p,finalUrl:e,status:$.status,title:e.split("/").pop()||"GitHub File",byline:"",siteName:"GitHub",lang:"",publishedTime:E,lastModified:E,markdown:y,contentLength:y.length,excerpt:y.slice(0,300).replaceAll(/\n/g," "),needsBrowser:!1}}if(!_.includes("text/html")&&!_.includes("application/xhtml"))return{ok:!1,url:t,finalUrl:e,status:$.status,error:`Unsupported content type: ${_}`,needsBrowser:!1};let D=await $.text(),v=Pf($.status,D,e,t);if(v.blocked)return{ok:!1,url:t,finalUrl:e,status:$.status,error:`Blocked: ${v.reason}`,needsBrowser:!0};let P=await Rf(D,e),R=yf(P);if(!R.ok)return{ok:!1,url:t,finalUrl:e,status:$.status,error:`Low quality content: ${R.reason}`,needsBrowser:!0};return{ok:!0,url:t,finalUrl:e,status:$.status,title:P.title,byline:P.byline,siteName:P.siteName,lang:P.lang,publishedTime:P.publishedTime||E,lastModified:E,markdown:P.markdown,excerpt:P.excerpt,contentLength:P.markdown.length,needsBrowser:!1}}catch($){clearTimeout(w);let _=up($);return{ok:!1,url:t,finalUrl:t,status:0,error:$.message,needsBrowser:_}}}function Pf(t,n,f,p){let g=n.match(/<title[^>]*>([^<]*)<\/title>/i)?.[1]?.toLowerCase()||"",r=n.slice(0,30000).toLowerCase(),a=`${g} ${r}`;if(t===403||t===429||t===503)return{blocked:!0,reason:`HTTP ${t}`};let l=[{pattern:/class=["'][^"']*captcha["']|<div[^>]*id=["']captcha/i,reason:"captcha"},{pattern:/g-recaptcha|data-sitekey|i['"]m not a robot/i,reason:"captcha"},{pattern:/checking your browser.{0,100}please wait|cf-browser-verification/i,reason:"cloudflare challenge"},{pattern:/just a moment.{0,50}security check|ddos protection by cloudflare/i,reason:"cloudflare challenge"},{pattern:/unusual traffic.{0,50}from your computer network/i,reason:"unusual traffic"},{pattern:/bot detected|automated.{0,20}request/i,reason:"bot detection"},{pattern:/enable\s+javascript\s+to\s+view|javascript\s+is\s+required.{0,50}enabled/i,reason:"requires javascript"},{pattern:/access denied|accessdenied/i,reason:"access denied"},{pattern:/protected by anubis|anubis uses a proof-of-work/i,reason:"anubis challenge"}];for(let $ of l)if($.pattern.test(a))return{blocked:!0,reason:$.reason};let w=sp(p,f,n);if(w)return{blocked:!0,reason:w};return{blocked:!1}}function sp(t,n,f){try{let p=new URL(t),g=new URL(n);if(p.hostname.toLowerCase()===g.hostname.toLowerCase())return;let r=g.hostname.toLowerCase();if(cp.some((l)=>r===l||r.endsWith(`.${l}`)))return`redirected to login (${g.hostname})`;if(dp.some((l)=>r.startsWith(l)))return`redirected to login (${g.hostname})`;let a=f.slice(0,20000).toLowerCase();if(qp.some((l)=>a.includes(l)))return`redirected to login page (${g.hostname})`}catch{}return}function up(t){let n=t.message.toLowerCase();return n.includes("fetch failed")||n.includes("unable to verify")||n.includes("certificate")||n.includes("timeout")}function lf(t){let n=['meta[property="article:published_time"]','meta[name="article:published_time"]','meta[property="og:published_time"]','meta[name="publication_date"]','meta[name="date"]','meta[itemprop="datePublished"]','time[itemprop="datePublished"]','meta[name="DC.date"]'];for(let f of n){let p=t.querySelector(f),g=p?.getAttribute("content")||p?.getAttribute("datetime")||"";if(g)return g}return""}async function Rf(t,n){let{Readability:f,JSDOM:p,turndown:g}=await Kp(),r=new p(t,{url:n});try{let a=r.window.document,l=new f(a).parse();if(l&&l.content){let $=g.turndown(l.content).replaceAll(/\n{3,}/g,`
2
10
 
3
- `).trim(),i=n.publishedTime||Te(r)||"";return{title:n.title||r.title||e,byline:n.byline||"",siteName:n.siteName||"",lang:n.lang||"",publishedTime:i,markdown:l,excerpt:l.slice(0,300).replaceAll(/\n/g," ")}}let a=r.body;if(a){let l=a.cloneNode(!0);l.querySelectorAll("script, style, nav, footer, header, aside").forEach((f)=>f.remove());let i=(l.textContent||"").replaceAll(/\s+/g," ").trim();return{title:r.title||e,byline:"",siteName:"",lang:"",publishedTime:Te(r),markdown:i,excerpt:i.slice(0,300)}}return{title:e,byline:"",siteName:"",lang:"",publishedTime:"",markdown:"",excerpt:""}}function Ve(t){let e=t.markdown.trim().toLowerCase(),r=(t.title||"").toLowerCase();if(t.markdown.trim().length<100)return{ok:!1,reason:"content too short (< 100 chars)"};let n=e.toLowerCase(),a=[{check:()=>n.includes("loading")&&n.includes("please wait"),desc:"loading page"},{check:()=>n.includes("please ensure javascript is enabled"),desc:"requires javascript"},{check:()=>n.includes("enable javascript to view"),desc:"requires javascript"},{check:()=>n.includes("just a moment"),desc:"cloudflare challenge detected in content"},{check:()=>n.includes("verify you are human"),desc:"human verification"},{check:()=>n.includes("captcha required"),desc:"captcha in extracted content"},{check:()=>n.includes("access denied"),desc:"access denied in content"},{check:()=>/^\s{0,10}sign\s{1,5}in\s{0,10}$|^\s{0,10}log\s{1,5}in\s{0,10}$/im.test(e),desc:"login form only"}];for(let{check:l,desc:i}of a)if(l())return{ok:!1,reason:i};if(r.includes("just a moment")||r.includes("checking your browser"))return{ok:!1,reason:"cloudflare challenge page detected in title"};return{ok:!0}}function Yt(t){try{let e=new URL(t);if(!(e.hostname==="github.com"||e.hostname.endsWith(".github.com")))return null;let r=e.pathname.split("/").filter(Boolean);if(r.length<2)return null;let[n,a]=r;if(r.length===2)return{owner:n,repo:a,type:"root"};if(r.length>=4&&(r[2]==="blob"||r[2]==="tree")){let l=r[2],i=r[3],f=r.slice(4).join("/");return{owner:n,repo:a,type:l,ref:i,path:f}}return null}catch{return null}}async function K(t,e=1e4){let r=new AbortController,n=setTimeout(()=>r.abort(),e);try{let a=await fetch(`https://api.github.com${t}`,{headers:Ze,signal:r.signal});if(clearTimeout(n),!a.ok)throw Error(`GitHub API ${a.status}: ${t}`);return await a.json()}catch(a){throw clearTimeout(n),a}}async function Nn(t,e){try{let r=await K(`/repos/${t}/${e}/readme`);if(r.content&&r.encoding==="base64")return Buffer.from(r.content,"base64").toString("utf8");return""}catch{return""}}async function Oe(t,e,r="HEAD",n=""){try{let a=await K(`/repos/${t}/${e}/git/ref/heads/${r==="HEAD"?"main":r}`).catch(()=>K(`/repos/${t}/${e}/git/ref/heads/master`).catch(()=>null)),l;if(a?.object?.sha)l=(await K(`/repos/${t}/${e}/git/commits/${a.object.sha}`)).tree.sha;else{let f=await K(`/repos/${t}/${e}`);l=(await K(`/repos/${t}/${e}/branches/${f.default_branch}`)).commit.commit.tree.sha}let i=(await K(`/repos/${t}/${e}/git/trees/${l}`)).tree||[];if(n)i=i.filter((f)=>f.path.startsWith(n));return i.slice(0,50).map((f)=>({path:f.path,type:f.type==="tree"?"dir":"file",size:f.size}))}catch{return[]}}async function Tn(t,e,r,n,a=1e4){let l=[`https://raw.githubusercontent.com/${t}/${e}/${r&&r!=="HEAD"?r:"main"}/${n}`,`https://raw.githubusercontent.com/${t}/${e}/master/${n}`];for(let i of l){let f=new AbortController,o=setTimeout(()=>f.abort(),a);try{let g=await fetch(i,{headers:{"user-agent":Ze["user-agent"]},signal:f.signal});if(clearTimeout(o),g.ok)return await g.text()}catch{clearTimeout(o)}}return null}async function On(t){let e=Yt(t);if(!e)return{ok:!1,error:"Not a valid GitHub URL"};let{owner:r,repo:n,type:a,ref:l,path:i}=e;try{if(a==="root"||a==="tree"&&!i){let[f,o,g]=await Promise.allSettled([K(`/repos/${r}/${n}`),Nn(r,n),Oe(r,n,l||"HEAD")]);if(f.status==="rejected")return{ok:!1,error:f.reason?.message||"Repo not found"};let p=f.value,h=o.status==="fulfilled"?o.value:"",m=g.status==="fulfilled"?g.value:[],c=p?.description?`
11
+ `).trim(),_=l.publishedTime||lf(a)||"";return{title:l.title||a.title||n,byline:l.byline||"",siteName:l.siteName||"",lang:l.lang||"",publishedTime:_,markdown:$,excerpt:$.slice(0,300).replaceAll(/\n/g," ")}}let w=a.body;if(w){let $=w.cloneNode(!0);$.querySelectorAll("script, style, nav, footer, header, aside").forEach((e)=>e.remove());let _=($.textContent||"").replaceAll(/\s+/g," ").trim();return{title:a.title||n,byline:"",siteName:"",lang:"",publishedTime:lf(a),markdown:_,excerpt:_.slice(0,300)}}return{title:n,byline:"",siteName:"",lang:"",publishedTime:"",markdown:"",excerpt:""}}finally{r.window.close()}}function yf(t){let n=t.markdown.trim().toLowerCase(),f=(t.title||"").toLowerCase();if(t.markdown.trim().length<100)return{ok:!1,reason:"content too short (< 100 chars)"};let p=n.toLowerCase(),g=[{check:()=>p.includes("loading")&&p.includes("please wait"),desc:"loading page"},{check:()=>p.includes("please ensure javascript is enabled"),desc:"requires javascript"},{check:()=>p.includes("enable javascript to view"),desc:"requires javascript"},{check:()=>p.includes("just a moment"),desc:"cloudflare challenge detected in content"},{check:()=>p.includes("verify you are human"),desc:"human verification"},{check:()=>p.includes("captcha required"),desc:"captcha in extracted content"},{check:()=>p.includes("access denied"),desc:"access denied in content"},{check:()=>/^\s{0,10}sign\s{1,5}in\s{0,10}$|^\s{0,10}log\s{1,5}in\s{0,10}$/im.test(n),desc:"login form only"}];for(let{check:r,desc:a}of g)if(r())return{ok:!1,reason:a};if(f.includes("just a moment")||f.includes("checking your browser"))return{ok:!1,reason:"cloudflare challenge page detected in title"};return{ok:!0}}function _n(t){try{let n=new URL(t);if(!(n.hostname==="github.com"||n.hostname.endsWith(".github.com")))return null;let f=n.pathname.split("/").filter(Boolean);if(f.length<2)return null;let[p,g]=f;if(f.length===2)return{owner:p,repo:g,type:"root"};if(f.length>=4&&(f[2]==="blob"||f[2]==="tree")){let r=f[2],a=f[3],l=f.slice(4).join("/");return{owner:p,repo:g,type:r,ref:a,path:l}}return null}catch{return null}}async function B(t,n=1e4){let f=new AbortController,p=setTimeout(()=>f.abort(),n);try{let g=await fetch(`https://api.github.com${t}`,{headers:Of,signal:f.signal});if(clearTimeout(p),!g.ok)throw Error(`GitHub API ${g.status}: ${t}`);return await g.json()}catch(g){throw clearTimeout(p),g}}async function tg(t,n){try{let f=await B(`/repos/${t}/${n}/readme`);if(f.content&&f.encoding==="base64")return Buffer.from(f.content,"base64").toString("utf8");return""}catch{return""}}async function wf(t,n,f="HEAD",p="",g){try{let r;if(f==="HEAD")if(g)r=await B(`/repos/${t}/${n}/git/ref/heads/${g}`).catch(()=>null);else r=await Promise.any([B(`/repos/${t}/${n}/git/ref/heads/main`),B(`/repos/${t}/${n}/git/ref/heads/master`)]).catch(()=>null);else r=await B(`/repos/${t}/${n}/git/ref/heads/${f}`).catch(()=>B(`/repos/${t}/${n}/git/ref/heads/master`).catch(()=>null));if(!r?.object?.sha)return[];let a=(await B(`/repos/${t}/${n}/git/commits/${r.object.sha}`)).tree.sha,l=(await B(`/repos/${t}/${n}/git/trees/${a}`)).tree||[];if(p)l=l.filter((w)=>w.path.startsWith(p));return l.slice(0,50).map((w)=>({path:w.path,type:w.type==="tree"?"dir":"file",size:w.size}))}catch{return[]}}async function ng(t,n,f,p,g=1e4,r){let a=async(w)=>{let $=new AbortController,_=setTimeout(()=>$.abort(),g);try{let e=await fetch(w,{headers:{"user-agent":Of["user-agent"]},signal:$.signal});if(clearTimeout(_),e.ok)return await e.text();throw Error("not ok")}catch{throw clearTimeout(_),Error("failed")}};if(!f||f==="HEAD"){if(r)try{return await a(`https://raw.githubusercontent.com/${t}/${n}/${r}/${p}`)}catch{return null}try{return await Promise.any([a(`https://raw.githubusercontent.com/${t}/${n}/main/${p}`),a(`https://raw.githubusercontent.com/${t}/${n}/master/${p}`)])}catch{return null}}let l=[`https://raw.githubusercontent.com/${t}/${n}/${f}/${p}`,`https://raw.githubusercontent.com/${t}/${n}/master/${p}`];for(let w of l)try{return await a(w)}catch{}return null}async function fg(t){let n=_n(t);if(!n)return{ok:!1,error:"Not a valid GitHub URL"};let{owner:f,repo:p,type:g,ref:r,path:a}=n;try{if(g==="root"||g==="tree"&&!a){let l=await B(`/repos/${f}/${p}`),[w,$]=await Promise.allSettled([tg(f,p),wf(f,p,r||"HEAD","",l.default_branch)]),_=w.status==="fulfilled"?w.value:"",e=$.status==="fulfilled"?$.value:[],E=l?.description?`
4
12
 
5
- > ${p.description}`:"",y=p?.stargazers_count==null?"":` ⭐ ${p.stargazers_count}`,b=p?.language?` · ${p.language}`:"",w=`# ${r}/${n}${y}${b}${c}
13
+ > ${l.description}`:"",h=l?.stargazers_count==null?"":` ⭐ ${l.stargazers_count}`,b=l?.language?` · ${l.language}`:"",D=`# ${f}/${p}${h}${b}${E}
6
14
 
7
- `;if(h)w+=h.slice(0,6000);else w+=`[No README found]
15
+ `;if(_)D+=_.slice(0,6000);else D+=`[No README found]
8
16
 
9
17
  Files:
10
- ${m.map((k)=>` ${k.type==="dir"?"\uD83D\uDCC1":"\uD83D\uDCC4"} ${k.path}`).join(`
11
- `)}`;return{ok:!0,title:`${r}/${n}`,content:w,tree:m.slice(0,30)}}if(a==="blob"&&i){let f=await Tn(r,n,l,i);if(f===null)return{ok:!1,error:`File not found: ${i}`};return{ok:!0,title:`${r}/${n}: ${i}`,content:f}}if(a==="tree"&&i){let f=await Oe(r,n,l||"HEAD",i),o=f.map((g)=>` ${g.type==="dir"?"\uD83D\uDCC1":"\uD83D\uDCC4"} ${g.path}`).join(`
12
- `);return{ok:!0,title:`${r}/${n}/${i}`,content:`[Directory: ${i}]
18
+ ${e.map((v)=>` ${v.type==="dir"?"\uD83D\uDCC1":"\uD83D\uDCC4"} ${v.path}`).join(`
19
+ `)}`;return{ok:!0,title:`${f}/${p}`,content:D,tree:e.slice(0,30)}}if(g==="blob"&&a){let l;if(!r||r==="HEAD")try{l=(await B(`/repos/${f}/${p}`)).default_branch}catch{l=void 0}let w=await ng(f,p,r,a,1e4,l);if(w===null)return{ok:!1,error:`File not found: ${a}`};return{ok:!0,title:`${f}/${p}: ${a}`,content:w}}if(g==="tree"&&a){let l;if(!r||r==="HEAD")try{l=(await B(`/repos/${f}/${p}`)).default_branch}catch{l=void 0}let w=await wf(f,p,r||"HEAD",a,l),$=w.map((_)=>` ${_.type==="dir"?"\uD83D\uDCC1":"\uD83D\uDCC4"} ${_.path}`).join(`
20
+ `);return{ok:!0,title:`${f}/${p}/${a}`,content:`[Directory: ${a}]
13
21
 
14
22
  Files:
15
- ${o}`,tree:f}}return{ok:!1,error:"Unsupported GitHub URL type"}}catch(f){return{ok:!1,error:f.message}}}function Ln(t){try{let e=new URL(t),r=e.hostname.toLowerCase();if(!(r==="reddit.com"||r.endsWith(".reddit.com")))return null;let n=e.pathname;if(n.match(/^\/(u|user)\/[^/]+\/?$/i))return{type:"user",cleanUrl:Pe(t)};if(n.match(/^\/r\/[^/]+\/comments\/[^/]+/i))return{type:"post",cleanUrl:Pe(t)};return null}catch{return null}}function Pe(t){try{let e=new URL(t);return`${e.protocol}//${e.hostname}${e.pathname}`}catch{return t}}async function Wn(t,e=8000){let r=Date.now();try{let n=t.replaceAll(/\/?$/g,".json"),a=new AbortController,l=setTimeout(()=>a.abort(),15000),i=await fetch(n,{headers:Pn,signal:a.signal});if(clearTimeout(l),!i.ok)throw Error(`Reddit API ${i.status}`);let f=await i.json();if(!Array.isArray(f)||f.length<1)throw Error("Invalid Reddit API response structure");let o=f[0],g=f[1],p=o?.data?.children?.[0]?.data;if(!p)throw Error("No post data in Reddit response");let h=Mn(p,g,e);return{ok:!0,url:t,finalUrl:t,status:200,contentType:"text/markdown",lastModified:"",title:p.title||"Reddit Post",byline:`u/${p.author}`,siteName:`r/${p.subreddit}`,lang:"en",publishedTime:new Date(p.created_utc*1000).toISOString(),excerpt:p.selftext?.slice(0,300).replace(/\n/g," ")||"",markdown:h,contentLength:h.length,needsBrowser:!1,duration:Date.now()-r}}catch(n){return{ok:!1,url:t,finalUrl:t,status:0,error:`Reddit fetch failed: ${n.message}`,needsBrowser:!1,duration:Date.now()-r}}}function Mn(t,e,r){let n="";if(n+=`# ${t.title}
23
+ ${$}`,tree:w}}return{ok:!1,error:"Unsupported GitHub URL type"}}catch(l){return{ok:!1,error:l.message}}}function gg(t){try{let n=new URL(t),f=n.hostname.toLowerCase();if(!(f==="reddit.com"||f.endsWith(".reddit.com")))return null;let p=n.pathname;if(p.match(/^\/(u|user)\/[^/]+\/?$/i))return{type:"user",cleanUrl:$f(t)};if(p.match(/^\/r\/[^/]+\/comments\/[^/]+/i))return{type:"post",cleanUrl:$f(t)};return null}catch{return null}}function $f(t){try{let n=new URL(t);return`${n.protocol}//${n.hostname}${n.pathname}`}catch{return t}}async function ag(t,n=8000){let f=Date.now();try{let p=t.replace(/\/+$/,"")+".json",g=new AbortController,r=setTimeout(()=>g.abort(),15000),a=await fetch(p,{headers:pg,signal:g.signal});if(clearTimeout(r),!a.ok)throw Error(`Reddit API ${a.status}`);let l=await a.json();if(!Array.isArray(l)||l.length<1)throw Error("Invalid Reddit API response structure");let w=l[0],$=l[1],_=w?.data?.children?.[0]?.data;if(!_)throw Error("No post data in Reddit response");let e=rg(_,$,n);return{ok:!0,url:t,finalUrl:t,status:200,contentType:"text/markdown",lastModified:"",title:_.title||"Reddit Post",byline:`u/${_.author}`,siteName:`r/${_.subreddit}`,lang:"en",publishedTime:new Date(_.created_utc*1000).toISOString(),excerpt:_.selftext?.slice(0,300).replace(/\n/g," ")||"",markdown:e,contentLength:e.length,needsBrowser:!1,duration:Date.now()-f}}catch(p){return{ok:!1,url:t,finalUrl:t,status:0,error:`Reddit fetch failed: ${p.message}`,needsBrowser:!1,duration:Date.now()-f}}}function rg(t,n,f){let p="";if(p+=`# ${t.title}
16
24
 
17
- `,n+=`**Subreddit:** r/${t.subreddit} | **Author:** u/${t.author} | **Score:** ${t.score}
25
+ `,p+=`**Subreddit:** r/${t.subreddit} | **Author:** u/${t.author} | **Score:** ${t.score}
18
26
 
19
- `,t.selftext)n+=t.selftext,n+=`
27
+ `,t.selftext)p+=t.selftext,p+=`
20
28
 
21
- `;else if(t.url)try{let a=new URL(t.url).hostname.toLowerCase();if(a!=="reddit.com"&&!a.endsWith(".reddit.com"))n+=`**Link:** ${t.url}
29
+ `;else if(t.url)try{let g=new URL(t.url).hostname.toLowerCase();if(g!=="reddit.com"&&!g.endsWith(".reddit.com"))p+=`**Link:** ${t.url}
22
30
 
23
- `}catch{n+=`**Link:** ${t.url}
31
+ `}catch{p+=`**Link:** ${t.url}
24
32
 
25
- `}if(e?.data?.children?.length>0){n+=`---
33
+ `}if(n?.data?.children?.length>0){p+=`---
26
34
 
27
35
  ## Comments
28
36
 
29
- `;let a=e.data.children.filter((l)=>l.kind==="t1").slice(0,10);for(let l of a)n+=Be(l.data,0),n+=`
30
- `}if(n.length>r)n=n.slice(0,r).trim()+`
37
+ `;let g=n.data.children.filter((r)=>r.kind==="t1").slice(0,10);for(let r of g)p+=Nf(r.data,0),p+=`
38
+ `}if(p.length>f)p=p.slice(0,f).trim()+`
31
39
 
32
- ... (truncated)`;return n}function Be(t,e){if(!t||t.body==="[deleted]"||t.body==="[removed]")return"";let r="> ".repeat(e),n="";if(n+=`${r}**u/${t.author}** (${t.score} pts)
33
- `,n+=`${r}${t.body.replaceAll(`
40
+ ... (truncated)`;return p}function Nf(t,n){if(!t||t.body==="[deleted]"||t.body==="[removed]")return"";let f="> ".repeat(n),p="";if(p+=`${f}**u/${t.author}** (${t.score} pts)
41
+ `,p+=`${f}${t.body.replaceAll(`
34
42
  `,`
35
- `+r)}
36
- `,e<3&&t.replies?.data?.children){let a=t.replies.data.children.filter((l)=>l.kind==="t1");for(let l of a.slice(0,5))n+=`
37
- `+Be(l.data,e+1)}return n}function q(t,e=8000){if(!t||t.length<=e)return t;let r=`
43
+ `+f)}
44
+ `,n<3&&t.replies?.data?.children){let g=t.replies.data.children.filter((r)=>r.kind==="t1");for(let r of g.slice(0,5))p+=`
45
+ `+Nf(r.data,n+1)}return p}function Rt(t,n=8000){if(!t||t.length<=n)return t;let f=`
38
46
 
39
47
  [...content trimmed...]
40
48
 
41
- `,n=e-r.length,a=Math.floor(n*0.75),l=n-a,i=a;while(i>a-100&&t[i]!==`
42
- `)i--;if(i<=a-100)i=a;let f=t.length-l;while(f<t.length-l+100&&t[f]!==`
43
- `)f++;if(f>=t.length-l+100)f=t.length-l;let o=t.slice(0,i).trimEnd(),g=t.slice(f).trimStart();return`${o}${r}${g}`}function In(t=process.env,e=process.execPath){let r=t.GREEDY_SEARCH_NODE||t.NODE_BINARY||t.NODE;if(r?.trim())return r.trim();let n=Fn(e||"").toLowerCase();if(n==="node"||n==="node.exe")return e;return"node"}function xe(t,e=30000){return Qn(t,null,e)}function Qn(t,e=null,r=30000){return new Promise((n,a)=>{let l=Rn(In(),[xn,...t],{stdio:[e==null?"ignore":"pipe","pipe","pipe"]});if(e!=null)l.stdin.write(e),l.stdin.end();let i="",f="";l.stdout.on("data",(g)=>i+=g),l.stderr.on("data",(g)=>f+=g);let o=setTimeout(()=>{l.kill(),a(Error(`cdp timeout: ${t[0]}`))},r);l.on("close",(g)=>{if(clearTimeout(o),g===0)n(i.trim());else a(Error(f.trim()||`cdp exit ${g}`))})})}async function Le(t){await xe(["evalraw",t,"Page.addScriptToEvaluateOnNewDocument",JSON.stringify({source:`
49
+ `,p=n-f.length,g=Math.floor(p*0.75),r=p-g,a=g;while(a>g-100&&t[a]!==`
50
+ `)a--;if(a<=g-100)a=g;let l=t.length-r;while(l<t.length-r+100&&t[l]!==`
51
+ `)l++;if(l>=t.length-r+100)l=t.length-r;let w=t.slice(0,a).trimEnd(),$=t.slice(l).trimStart();return`${w}${f}${$}`}function Rg(t=process.env,n=process.execPath){let f=t.GREEDY_SEARCH_NODE||t.NODE_BINARY||t.NODE;if(f?.trim())return f.trim();let p=wg(n||"").toLowerCase();if(p==="node"||p==="node.exe")return n;return"node"}function ig(t){if(!Array.isArray(t)||t.length===0)throw Error("cdp: args must be a non-empty array");if(t[0]==="test")return t.map((n,f)=>_f(n,f));if(!Ng.has(t[0]))throw Error(`cdp: unknown subcommand '${t[0]}'`);return t.map((n,f)=>_f(n,f))}function _f(t,n){if(typeof t!=="string")throw Error(`cdp: argv[${n}] must be a string (got ${typeof t})`);if(t.includes("\x00"))throw Error(`cdp: argv[${n}] contains a null byte`);return t}function Lf(t,n=30000){return Ag(t,null,n)}function Ag(t,n=null,f=30000){let p=ig(t);return new Promise((g,r)=>{let a=lg(Rg(),[Og,...p],{stdio:[n==null?"ignore":"pipe","pipe","pipe"]});if(n!=null)a.stdin.write(n),a.stdin.end();let l="",w="";a.stdout.on("data",(_)=>l+=_),a.stderr.on("data",(_)=>w+=_);let $=setTimeout(()=>{a.kill(),r(Error(`cdp timeout: ${t[0]}`))},f);a.on("close",(_)=>{if(clearTimeout($),_===0)g(l.trim());else r(Error(w.trim()||`cdp exit ${_}`))})})}async function hf(t){await Lf(["evalraw",t,"Page.addScriptToEvaluateOnNewDocument",JSON.stringify({source:`
44
52
  (function() {
45
53
  // ── Runtime.enable / CDP detection masking ──────────────
46
54
  try { delete window.__REBROWSER_RUNTIME_ENABLE; } catch(_) {}
@@ -51,40 +59,62 @@ ${o}`,tree:f}}return{ok:!1,error:"Unsupported GitHub URL type"}}catch(f){return{
51
59
  try { delete window._phantom; } catch(_) {}
52
60
  try { delete window.Buffer; } catch(_) {}
53
61
 
54
- // Real Chrome without automation does not expose a useful webdriver value.
55
- // A literal false value is itself a common stealth tell; prefer undefined and
56
- // make the descriptor configurable like native browser properties.
57
- Object.defineProperty(navigator, 'webdriver', { get: () => undefined, configurable: true });
62
+ // Real Chrome without automation should not expose navigator.webdriver at all.
63
+ // A literal false or an own-property getter returning undefined is itself a
64
+ // common stealth tell; remove both instance and prototype properties when the
65
+ // descriptor is configurable (as it is with --disable-blink-features).
66
+ try { delete navigator.webdriver; } catch(_) {}
67
+ try { delete Navigator.prototype.webdriver; } catch(_) {}
58
68
  Object.defineProperty(navigator, 'vendor', { get: () => 'Google Inc.', configurable: true });
59
69
  Object.defineProperty(navigator, 'platform', { get: () => 'Win32', configurable: true });
60
70
  Object.defineProperty(navigator, 'maxTouchPoints', { get: () => 0, configurable: true });
61
71
  Object.defineProperty(navigator, 'pdfViewerEnabled', { get: () => true, configurable: true });
72
+ Object.defineProperty(navigator, 'productSub', { get: () => '20030107', configurable: true });
73
+ Object.defineProperty(navigator, 'product', { get: () => 'Gecko', configurable: true });
74
+ var __greedyMimeTypes = null;
75
+ function __makeMimeTypes() {
76
+ var pdf = { type: 'application/pdf', suffixes: 'pdf', description: 'Portable Document Format', enabledPlugin: null };
77
+ var textPdf = { type: 'text/pdf', suffixes: 'pdf', description: 'Portable Document Format', enabledPlugin: null };
78
+ try { Object.setPrototypeOf(pdf, MimeType.prototype); } catch(_) {}
79
+ try { Object.setPrototypeOf(textPdf, MimeType.prototype); } catch(_) {}
80
+ var m = [pdf, textPdf];
81
+ try { Object.setPrototypeOf(m, MimeTypeArray.prototype); } catch(_) {}
82
+ m.item = function item(i) { return this[i] || null; };
83
+ m.namedItem = function namedItem(name) { return Array.prototype.find.call(this, function(x) { return x && x.type === name; }) || null; };
84
+ return m;
85
+ }
62
86
  Object.defineProperty(navigator, 'plugins', {
63
87
  get: () => {
64
- var p = [
65
- { name: 'Chrome PDF Plugin', filename: 'internal-pdf-viewer', description: 'Portable Document Format' },
66
- { name: 'Chrome PDF Viewer', filename: 'mhjfbmdgcfjbbpaeojofohoefgiehjai', description: '' },
67
- { name: 'Native Client', filename: 'internal-nacl-plugin', description: '' },
68
- ];
69
- p.length = 3;
88
+ __greedyMimeTypes = __greedyMimeTypes || __makeMimeTypes();
89
+ var plugin0 = { name: 'Chrome PDF Plugin', filename: 'internal-pdf-viewer', description: 'Portable Document Format' };
90
+ var plugin1 = { name: 'Chrome PDF Viewer', filename: 'mhjfbmdgcfjbbpaeojofohoefgiehjai', description: '' };
91
+ var plugin2 = { name: 'Native Client', filename: 'internal-nacl-plugin', description: '' };
92
+ try { Object.setPrototypeOf(plugin0, Plugin.prototype); } catch(_) {}
93
+ try { Object.setPrototypeOf(plugin1, Plugin.prototype); } catch(_) {}
94
+ try { Object.setPrototypeOf(plugin2, Plugin.prototype); } catch(_) {}
95
+ var p = [plugin0, plugin1, plugin2];
96
+ p.item = function item(i) { return this[i] || null; };
97
+ p.namedItem = function namedItem(name) { return Array.prototype.find.call(this, function(x) { return x && x.name === name; }) || null; };
98
+ p.refresh = function refresh() {};
99
+ try { Object.setPrototypeOf(p, PluginArray.prototype); } catch(_) {}
100
+ try {
101
+ __greedyMimeTypes[0].enabledPlugin = p[0];
102
+ __greedyMimeTypes[1].enabledPlugin = p[0];
103
+ } catch(_) {}
70
104
  return p;
71
105
  },
106
+ configurable: true,
72
107
  });
73
108
  Object.defineProperty(navigator, 'mimeTypes', {
74
109
  get: () => {
75
- var m = [
76
- { type: 'application/pdf', suffixes: 'pdf', description: 'Portable Document Format', enabledPlugin: null },
77
- { type: 'text/pdf', suffixes: 'pdf', description: 'Portable Document Format', enabledPlugin: null },
78
- ];
79
- m.item = function(i) { return m[i] || null; };
80
- m.namedItem = function(name) { return m.find(function(x) { return x.type === name; }) || null; };
81
- return m;
110
+ __greedyMimeTypes = __greedyMimeTypes || __makeMimeTypes();
111
+ return __greedyMimeTypes;
82
112
  },
83
113
  configurable: true,
84
114
  });
85
115
  Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'], configurable: true });
86
116
  try {
87
- Object.defineProperty(navigator, 'connection', { get: () => ({ effectiveType: '4g', rtt: 50, downlink: 10, saveData: false }), configurable: true });
117
+ Object.defineProperty(navigator, 'connection', { get: () => ({ effectiveType: '4g', rtt: 50, downlink: 10, downlinkMax: Infinity, saveData: false }), configurable: true });
88
118
  } catch(_) {}
89
119
  if (!navigator.mediaDevices) {
90
120
  Object.defineProperty(navigator, 'mediaDevices', {
@@ -100,6 +130,18 @@ ${o}`,tree:f}}return{ok:!1,error:"Unsupported GitHub URL type"}}catch(f){return{
100
130
  configurable: true,
101
131
  });
102
132
  }
133
+ // ── Missing platform APIs (headless often lacks these) ─
134
+ try {
135
+ if (!navigator.share) {
136
+ navigator.share = function() { return Promise.reject(new Error('NotAllowedError')); };
137
+ }
138
+ } catch(_) {}
139
+ try {
140
+ if (!navigator.contentIndex) {
141
+ Object.defineProperty(navigator, 'contentIndex', { get: () => ({ add: function() {}, delete: function() {}, getAll: function() { return Promise.resolve([]); } }), configurable: true });
142
+ }
143
+ } catch(_) {}
144
+
103
145
  if (!window.chrome) {
104
146
  window.chrome = {
105
147
  app: { isInstalled: false, InstallState: {}, RunningState: {} },
@@ -107,8 +149,8 @@ ${o}`,tree:f}}return{ok:!1,error:"Unsupported GitHub URL type"}}catch(f){return{
107
149
  OnInstalledReason: {}, OnRestartRequiredReason: {}, PlatformArch: {}, PlatformNaclArch: {}, PlatformOs: {}, RequestUpdateCheckStatus: {},
108
150
  connect: () => ({}), sendMessage: () => {}, onMessage: { addListener: () => {} }
109
151
  },
110
- loadTimes: () => ({}),
111
- csi: () => ({}),
152
+ loadTimes: function() { return { requestTime: 0, startLoadTime: Date.now() - 5000, commitLoadTime: Date.now() - 3000, finishDocumentLoadTime: Date.now() - 2000, finishLoadTime: Date.now() - 1000, firstPaintTime: Date.now() - 800, navigationType: 'Other', wasFetchedViaSpdy: true, wasNpnNegotiated: true, npnNegotiatedProtocol: 'h2', wasAlternateProtocolAvailable: false, connectionInfo: 'http/2' }; },
153
+ csi: function() { var t = Date.now(); return { onloadT: t - 2000, startE: t - 5000, pageT: 'back', tran: 2 }; },
112
154
  };
113
155
  }
114
156
  var __greedyNativeFns = [];
@@ -129,6 +171,19 @@ ${o}`,tree:f}}return{ok:!1,error:"Unsupported GitHub URL type"}}catch(f){return{
129
171
  return getParam.call(this, p);
130
172
  });
131
173
  } catch(_) {}
174
+ // ── WebGL readPixels noise ──────────────────────────
175
+ // CreepJS and other fingerprinters draw content with WebGL and read back the
176
+ // rendered pixels. Adding subtle noise breaks rendering-based fingerprinting.
177
+ try {
178
+ var origReadPixels = WebGLRenderingContext.prototype.readPixels;
179
+ WebGLRenderingContext.prototype.readPixels = __markNative(function readPixels(x, y, width, height, format, type, pixels) {
180
+ var result = origReadPixels.call(this, x, y, width, height, format, type, pixels);
181
+ if (pixels && pixels.length > 0) {
182
+ pixels[0] ^= 1;
183
+ }
184
+ return result;
185
+ });
186
+ } catch(_) {}
132
187
  Object.defineProperty(navigator, 'hardwareConcurrency', { get: () => 8, configurable: true });
133
188
  Object.defineProperty(navigator, 'deviceMemory', { get: () => 8, configurable: true });
134
189
 
@@ -136,7 +191,7 @@ ${o}`,tree:f}}return{ok:!1,error:"Unsupported GitHub URL type"}}catch(f){return{
136
191
  // Headless rendering engines produce slightly different canvas output
137
192
  // than headed Chrome. Subtle noise breaks hash-based fingerprinting.
138
193
  try {
139
- var __canvasNoise = ((Date.now() % 997) + Math.floor(Math.random() * 997)) & 1;
194
+ var __canvasNoise = ((Date.now() & 0xFF) | 1);
140
195
  var origFill = CanvasRenderingContext2D.prototype.fillText;
141
196
  CanvasRenderingContext2D.prototype.fillText = __markNative(function fillText() {
142
197
  this.globalAlpha = 0.9995;
@@ -155,15 +210,39 @@ ${o}`,tree:f}}return{ok:!1,error:"Unsupported GitHub URL type"}}catch(f){return{
155
210
  HTMLCanvasElement.prototype.toDataURL = __markNative(function toDataURL() {
156
211
  var ctx = this.getContext('2d');
157
212
  if (ctx) {
158
- // Add 1px noise pixel in corner (invisible but changes hash)
159
- var imgData = ctx.getImageData(0, 0, 1, 1);
160
- if (imgData) imgData.data[0] ^= __canvasNoise;
161
- ctx.putImageData(imgData, 0, 0);
213
+ // Spread noise across canvas to break hash-based fingerprinting.
214
+ // Uses a deterministic pattern so it's consistent per page load
215
+ // but varies between sessions.
216
+ var w = this.width, h = this.height;
217
+ if (w > 0 && h > 0) {
218
+ var imgData = ctx.getImageData(0, 0, Math.min(w, 4), Math.min(h, 4));
219
+ if (imgData && imgData.data) {
220
+ for (var __i = 0; __i < imgData.data.length; __i += 4) {
221
+ imgData.data[__i] ^= (__canvasNoise + __i) & 0xFF;
222
+ }
223
+ ctx.putImageData(imgData, 0, 0);
224
+ }
225
+ }
162
226
  }
163
227
  return origToDataURL.apply(this, arguments);
164
228
  });
165
229
  } catch(_) {}
166
230
 
231
+ // ── AudioContext fingerprint noise ────────────────────
232
+ // Headless Chrome's AudioContext produces slightly different output.
233
+ // Subtle noise breaks audio-based fingerprinting.
234
+ try {
235
+ var __audioSeed = ((Date.now() & 0x1F) | 1);
236
+ var origGetChannelData = AudioBuffer.prototype.getChannelData;
237
+ AudioBuffer.prototype.getChannelData = __markNative(function getChannelData(channel) {
238
+ var data = origGetChannelData.call(this, channel);
239
+ for (var __i = 0; __i < data.length; __i += 64) {
240
+ data[__i] *= 0.99999;
241
+ }
242
+ return data;
243
+ });
244
+ } catch(_) {}
245
+
167
246
  // ── window outer dimensions ──────────────────────────
168
247
  // outerWidth/Height = 0 in headless — a well-known bot signal.
169
248
  // Mirror innerWidth/Height (set by --window-size flag) so the ratio is sane.
@@ -173,9 +252,15 @@ ${o}`,tree:f}}return{ok:!1,error:"Unsupported GitHub URL type"}}catch(f){return{
173
252
  } catch(_) {}
174
253
 
175
254
  // ── screen properties ─────────────────────────────────
255
+ // Headless Chrome often reports an 800x600 screen even when the viewport is
256
+ // 1920x1080. Keep screen metrics internally consistent with our launch flags.
176
257
  try {
177
- if (!screen.colorDepth) Object.defineProperty(screen, 'colorDepth', { get: () => 24, configurable: true });
178
- if (!screen.pixelDepth) Object.defineProperty(screen, 'pixelDepth', { get: () => 24, configurable: true });
258
+ Object.defineProperty(screen, 'width', { get: () => 1920, configurable: true });
259
+ Object.defineProperty(screen, 'height', { get: () => 1080, configurable: true });
260
+ Object.defineProperty(screen, 'availWidth', { get: () => 1920, configurable: true });
261
+ Object.defineProperty(screen, 'availHeight', { get: () => 1040, configurable: true });
262
+ Object.defineProperty(screen, 'colorDepth', { get: () => 24, configurable: true });
263
+ Object.defineProperty(screen, 'pixelDepth', { get: () => 24, configurable: true });
179
264
  } catch(_) {}
180
265
 
181
266
  // ── navigator.userAgentData (UA Client Hints) ─────────
@@ -248,35 +333,35 @@ ${o}`,tree:f}}return{ok:!1,error:"Unsupported GitHub URL type"}}catch(f){return{
248
333
  };
249
334
  } catch(_) {}
250
335
  })();
251
- `})])}function zn(){try{if(mt(G)){let t=Ke(G,"utf8"),e=JSON.parse(t);if(Array.isArray(e.engines)&&e.engines.length>0&&e.engines.every((r)=>typeof r==="string")){let r=e.engines.filter((a)=>dt[a]),n=e.engines.filter((a)=>!dt[a]);if(n.length>0)process.stderr.write(`[greedysearch] Warning: ignoring unknown engine(s) in ${G}: ${n.join(", ")}
252
- [greedysearch] Available engines: ${Object.keys(dt).join(", ")}
253
- `);if(r.length>0)return r;process.stderr.write(`[greedysearch] Warning: no valid engines in ${G}, falling back to defaults: ${Vt.join(", ")}
254
- `)}}}catch{}return Vt}function Sn(){try{if(!mt(Gt))Yn(Gt,{recursive:!0});if(!mt(G))Gn(G,JSON.stringify({engines:Vt,synthesizer:Zt},null,2)+`
255
- `,"utf8")}catch{}}function un(){try{if(mt(G)){let t=Ke(G,"utf8"),e=JSON.parse(t);if(typeof e.synthesizer==="string"){let r=e.synthesizer.toLowerCase();if(We.includes(r))return r;process.stderr.write(`[greedysearch] Warning: unknown synthesizer "${e.synthesizer}" in ${G}
256
- [greedysearch] Available synthesizers: ${We.join(", ")}
257
- [greedysearch] Falling back to default: ${Zt}
258
- `)}}}catch{}return Zt}function qn(){try{if(bt(V)){let t=Ie(V,"utf8"),e=JSON.parse(t);if(Array.isArray(e.engines)&&e.engines.length>0&&e.engines.every((r)=>typeof r==="string")){let r=e.engines.filter((a)=>Ht[a]),n=e.engines.filter((a)=>!Ht[a]);if(n.length>0)process.stderr.write(`[greedysearch] Warning: ignoring unknown engine(s) in ${V}: ${n.join(", ")}
259
- [greedysearch] Available engines: ${Object.keys(Ht).join(", ")}
260
- `);if(r.length>0)return r;process.stderr.write(`[greedysearch] Warning: no valid engines in ${V}, falling back to defaults: ${Kt.join(", ")}
261
- `)}}}catch{}return Kt}function ta(){try{if(!bt(Bt))Bn(Bt,{recursive:!0});if(!bt(V))Kn(V,JSON.stringify({engines:Kt,synthesizer:Ut},null,2)+`
262
- `,"utf8")}catch{}}function ea(){try{if(bt(V)){let t=Ie(V,"utf8"),e=JSON.parse(t);if(typeof e.synthesizer==="string"){let r=e.synthesizer.toLowerCase();if(Me.includes(r))return r;process.stderr.write(`[greedysearch] Warning: unknown synthesizer "${e.synthesizer}" in ${V}
263
- [greedysearch] Available synthesizers: ${Me.join(", ")}
264
- [greedysearch] Falling back to default: ${Ut}
265
- `)}}}catch{}return Ut}async function ue(){let t=(await P(["list"])).split(`
266
- `)[0];if(!t)throw Error("No Chrome tabs found");return t.slice(0,8)}async function Qt(t="about:blank"){let e=await ue(),r=new URL(t).hostname;if(r==="copilot.microsoft.com"||r==="www.perplexity.ai"||r==="perplexity.ai"||r.endsWith(".perplexity.ai")){let l=await P(["evalraw",e,"Target.createTarget",JSON.stringify({url:"about:blank"})]),{targetId:i}=JSON.parse(l),f=i.slice(0,8);if(await P(["list"]).catch(()=>null),r==="copilot.microsoft.com")await Le(f);else Le(f).catch(()=>{});return await P(["list"]).catch(()=>null),i}let n=await P(["evalraw",e,"Target.createTarget",JSON.stringify({url:t})]),{targetId:a}=JSON.parse(n);return await P(["list"]).catch(()=>null),a}async function zt(t){try{let e=await ue();await P(["evalraw",e,"Target.closeTarget",JSON.stringify({targetId:t})])}catch{}}function la(){try{if(yt(Z)){let t=qe(Z,"utf8"),e=JSON.parse(t);if(Array.isArray(e.engines)&&e.engines.length>0&&e.engines.every((r)=>typeof r==="string")){let r=e.engines.filter((a)=>Ft[a]),n=e.engines.filter((a)=>!Ft[a]);if(n.length>0)process.stderr.write(`[greedysearch] Warning: ignoring unknown engine(s) in ${Z}: ${n.join(", ")}
267
- [greedysearch] Available engines: ${Object.keys(Ft).join(", ")}
268
- `);if(r.length>0)return r;process.stderr.write(`[greedysearch] Warning: no valid engines in ${Z}, falling back to defaults: ${Xt.join(", ")}
269
- `)}}}catch{}return Xt}function ia(){try{if(!yt(It))ra(It,{recursive:!0});if(!yt(Z))na(Z,JSON.stringify({engines:Xt,synthesizer:xt},null,2)+`
270
- `,"utf8")}catch{}}function fa(){try{if(yt(Z)){let t=qe(Z,"utf8"),e=JSON.parse(t);if(typeof e.synthesizer==="string"){let r=e.synthesizer.toLowerCase();if(Ae.includes(r))return r;process.stderr.write(`[greedysearch] Warning: unknown synthesizer "${e.synthesizer}" in ${Z}
271
- [greedysearch] Available synthesizers: ${Ae.join(", ")}
272
- [greedysearch] Falling back to default: ${xt}
273
- `)}}}catch{}return xt}function ga(){if(typeof globalThis.DOMMatrix>"u")globalThis.DOMMatrix=class{constructor(t=void 0){}multiplySelf(){return this}preMultiplySelf(){return this}translateSelf(){return this}scaleSelf(){return this}rotateSelf(){return this}};if(typeof globalThis.ImageData>"u")globalThis.ImageData=class{constructor(t=void 0,e=0,r=0){this.data=t,this.width=e,this.height=r}};if(typeof globalThis.Path2D>"u")globalThis.Path2D=class{constructor(t=void 0){}}}async function oa(){ga();let t=await import("pdf-parse"),e=t.PDFParse??t.default;if(!e)throw Error("pdf-parse did not export PDFParse");return e}async function pa(t,e){try{let r=new(await oa())({data:new Uint8Array(t)});await r.load();let n=await r.getText(),a=n.text?.trim();if(!a)return null;return{title:new URL(e).pathname.split("/").pop()||"Document.pdf",content:`## PDF Content (${n.total} pages)
274
-
275
- ${a}`,pages:n.total}}catch(r){return{error:r.message||String(r)}}}function rr(t="",e=240){let r=String(t).replaceAll(/\s+/g," ").trim();if(r.length<=e)return r;let n=r.slice(0,e),a=n.lastIndexOf(" ");return a>0?`${n.slice(0,a)}...`:`${n}...`}async function ha(t,e,r=8000){let n=Date.now();try{let a=(await P(["evalraw",t,"Page.getFrameTree","{}"]).then((m)=>JSON.parse(m)).catch(()=>null))?.frameTree?.frame?.id||void 0,l=await P(["evalraw",t,"Network.loadNetworkResource",JSON.stringify({frameId:a,url:e,options:{disableCache:!0,includeCredentials:!1}})],20000),i=JSON.parse(l).resource;if(!i?.success||!i.httpStatusCode)return{url:e,error:i?.netErrorName||i?.netError||"loadNetworkResource failed",source:"chrome",duration:Date.now()-n,needsFallback:!0};let f="";if(i.stream)try{let m=await P(["evalraw",t,"IO.read",JSON.stringify({handle:i.stream})],1e4);f=JSON.parse(m).data||"",await P(["evalraw",t,"IO.close",JSON.stringify({handle:i.stream})]).catch(()=>{})}catch{}if(!f||f.length<100)return{url:e,error:"Empty response body from Network.loadNetworkResource",source:"chrome",duration:Date.now()-n,needsFallback:!0};let o=Ye(i.httpStatusCode,f,e,e);if(o.blocked)return{url:e,status:i.httpStatusCode,error:`Blocked: ${o.reason}`,source:"chrome",duration:Date.now()-n,needsBrowser:!0};let g=Ge(f,e),p=Ve(g);if(!p.ok)return{url:e,status:i.httpStatusCode,error:`Low quality: ${p.reason}`,source:"chrome",duration:Date.now()-n,needsBrowser:!0};let h=q(g.markdown,r);return{url:e,finalUrl:e,status:i.httpStatusCode,contentType:"text/markdown",lastModified:"",publishedTime:g.publishedTime||"",byline:g.byline||"",siteName:g.siteName||"",lang:g.lang||"",title:g.title||e,snippet:g.excerpt,content:h,contentChars:h.length,source:"chrome",duration:Date.now()-n}}catch(a){return{url:e,error:a.message,source:"chrome",duration:Date.now()-n,needsFallback:!0}}}function nr(t){try{return new URL(t).pathname.toLowerCase().endsWith(".pdf")}catch{return!1}}async function wa(t,e=8000){let r=Fe(t);if(r.blocked)return{url:t,finalUrl:t,status:403,error:`Blocked: ${r.reason}`,source:"pdf-http"};let n=new AbortController,a=setTimeout(()=>n.abort(),20000),l=Date.now();try{let i=await fetch(t,{method:"GET",redirect:"follow",signal:n.signal,headers:_n({accept:"application/pdf,application/octet-stream;q=0.9,*/*;q=0.5"})});clearTimeout(a);let f=i.headers.get("content-type")||"",o=i.url||t,g=Number.parseInt(i.headers.get("content-length")||"0",10);if(i.status>=400)return{url:t,finalUrl:o,status:i.status,error:`HTTP ${i.status}`,source:"pdf-http",duration:Date.now()-l};if(!f.toLowerCase().includes("application/pdf")&&!nr(o))return null;if(g>31457280)return{url:t,finalUrl:o,status:i.status,error:`PDF too large: ${g} bytes`,source:"pdf-http",duration:Date.now()-l};let p=Buffer.from(await i.arrayBuffer()),h=await pa(p,o);if(!h||h.error)return{url:t,finalUrl:o,status:i.status,error:h?.error||"PDF text extraction failed",source:"pdf-http",duration:Date.now()-l};let m=q(h.content,e);return{url:t,finalUrl:o,status:i.status,contentType:"application/pdf",lastModified:i.headers.get("last-modified")||"",title:h.title,snippet:rr(m,320),content:m,contentChars:m.length,pages:h.pages,source:"pdf-http",duration:Date.now()-l}}catch(i){return clearTimeout(a),{url:t,finalUrl:t,error:i.message||String(i),source:"pdf-http",duration:Date.now()-l}}}async function ar(t,e=8000){let r=Date.now();if(nr(t)){let a=await wa(t,e);if(a?.content||a?.status===403)return a}if(Yt(t)){let a=Yt(t);if(a&&(a.type==="root"||a.type==="tree"||a.type==="blob"&&!a.path?.includes("."))){let l=await On(t);if(l.ok){let i=q(l.content,e);return{url:t,finalUrl:t,status:200,contentType:"text/markdown",lastModified:"",title:l.title,snippet:i.slice(0,320),content:i,contentChars:i.length,source:"github-api",...l.tree&&{tree:l.tree},duration:Date.now()-r}}process.stderr.write(`[greedysearch] GitHub API fetch failed, trying HTTP: ${l.error}
276
- `)}}if(Ln(t)?.type==="post"){process.stderr.write(`[greedysearch] Using Reddit JSON API for: ${t.slice(0,60)}...
277
- `);let a=await Wn(t,e);if(a.ok){let l=q(a.markdown,e);return{url:t,finalUrl:a.finalUrl,status:a.status,contentType:"text/markdown",lastModified:a.lastModified||"",publishedTime:a.publishedTime||"",byline:a.byline||"",siteName:a.siteName||"",lang:a.lang||"",title:a.title,snippet:a.excerpt,content:l,contentChars:l.length,source:"reddit-api",duration:Date.now()-r}}process.stderr.write(`[greedysearch] Reddit API fetch failed, falling back to HTTP: ${a.error}
278
- `)}let n=await sn(t,{timeoutMs:1e4});if(n.ok){let a=q(n.markdown,e);return{url:t,finalUrl:n.finalUrl,status:n.status,contentType:"text/markdown",lastModified:n.lastModified||"",publishedTime:n.publishedTime||"",byline:n.byline||"",siteName:n.siteName||"",lang:n.lang||"",title:n.title,snippet:n.excerpt,content:a,contentChars:a.length,source:"http",duration:Date.now()-r}}if(n.needsBrowser)try{let a=await Qt();try{let l=await ha(a,t,e);if(l.content&&l.content.length>100)return l}finally{await zt(a)}}catch{}return process.stderr.write(`[greedysearch] HTTP failed for ${t.slice(0,60)}, trying browser...
279
- `),await $a(t,e)}async function $a(t,e=8000){let r=Date.now(),n;try{n=await Qt()}catch(a){return{url:t,title:"",content:null,snippet:"",contentChars:0,error:`openNewTab failed: ${a.message}`,source:"browser",duration:Date.now()-r}}try{await P(["nav",n,t],30000),await new Promise((f)=>setTimeout(f,800));let a=await P(["eval",n,String.raw`
336
+ `})])}function Tg(t,n=9222){let f=Number.parseInt(String(t??""),10);return Number.isInteger(f)&&f>1024&&f<65535?f:n}function Hg(){try{if(Jt(pt)){let t=Af(pt,"utf8"),n=JSON.parse(t);if(Array.isArray(n.engines)&&n.engines.length>0&&n.engines.every((f)=>typeof f==="string")){let f=n.engines.filter((g)=>rn[g]),p=n.engines.filter((g)=>!rn[g]);if(p.length>0)process.stderr.write(`[greedysearch] Warning: ignoring unknown engine(s) in ${pt}: ${p.join(", ")}
337
+ [greedysearch] Available engines: ${Object.keys(rn).join(", ")}
338
+ `);if(f.length>0)return f;process.stderr.write(`[greedysearch] Warning: no valid engines in ${pt}, falling back to defaults: ${en.join(", ")}
339
+ `)}}}catch{}return en}function Lg(){try{if(!Jt(hn))eg(hn,{recursive:!0});if(!Jt(pt))Eg(pt,JSON.stringify({engines:en,synthesizer:En},null,2)+`
340
+ `,"utf8")}catch{}}function Yg(){try{if(Jt(pt)){let t=Af(pt,"utf8"),n=JSON.parse(t);if(typeof n.synthesizer==="string"){let f=n.synthesizer.toLowerCase();if(ef.includes(f))return f;process.stderr.write(`[greedysearch] Warning: unknown synthesizer "${n.synthesizer}" in ${pt}
341
+ [greedysearch] Available synthesizers: ${ef.join(", ")}
342
+ [greedysearch] Falling back to default: ${En}
343
+ `)}}}catch{}return En}function Ig(t,n=9222){let f=Number.parseInt(String(t??""),10);return Number.isInteger(f)&&f>1024&&f<65535?f:n}function Fg(){try{if(Zt(gt)){let t=kf(gt,"utf8"),n=JSON.parse(t);if(Array.isArray(n.engines)&&n.engines.length>0&&n.engines.every((f)=>typeof f==="string")){let f=n.engines.filter((g)=>ln[g]),p=n.engines.filter((g)=>!ln[g]);if(p.length>0)process.stderr.write(`[greedysearch] Warning: ignoring unknown engine(s) in ${gt}: ${p.join(", ")}
344
+ [greedysearch] Available engines: ${Object.keys(ln).join(", ")}
345
+ `);if(f.length>0)return f;process.stderr.write(`[greedysearch] Warning: no valid engines in ${gt}, falling back to defaults: ${bn.join(", ")}
346
+ `)}}}catch{}return bn}function Gg(){try{if(!Zt(Dn))Cg(Dn,{recursive:!0});if(!Zt(gt))vg(gt,JSON.stringify({engines:bn,synthesizer:Cn},null,2)+`
347
+ `,"utf8")}catch{}}function Wg(){try{if(Zt(gt)){let t=kf(gt,"utf8"),n=JSON.parse(t);if(typeof n.synthesizer==="string"){let f=n.synthesizer.toLowerCase();if(Ef.includes(f))return f;process.stderr.write(`[greedysearch] Warning: unknown synthesizer "${n.synthesizer}" in ${gt}
348
+ [greedysearch] Available synthesizers: ${Ef.join(", ")}
349
+ [greedysearch] Falling back to default: ${Cn}
350
+ `)}}}catch{}return Cn}async function Yf(){let t=(await G(["list"])).split(`
351
+ `)[0];if(!t)throw Error("No Chrome tabs found");return t.slice(0,8)}async function Rn(t="about:blank"){let n=await Yf(),f=new URL(t).hostname;if(f==="copilot.microsoft.com"||f==="www.perplexity.ai"||f==="perplexity.ai"||f.endsWith(".perplexity.ai")){let r=await G(["evalraw",n,"Target.createTarget",JSON.stringify({url:"about:blank"})]),{targetId:a}=JSON.parse(r),l=a.slice(0,8);if(await G(["list"]).catch(()=>null),f==="copilot.microsoft.com")await hf(l);else hf(l).catch(()=>{});return await G(["list"]).catch(()=>null),a}let p=await G(["evalraw",n,"Target.createTarget",JSON.stringify({url:t})]),{targetId:g}=JSON.parse(p);return await G(["list"]).catch(()=>null),g}async function yn(t){try{let n=await Yf();await G(["evalraw",n,"Target.closeTarget",JSON.stringify({targetId:t})])}catch{}}function Kg(t,n=9222){let f=Number.parseInt(String(t??""),10);return Number.isInteger(f)&&f>1024&&f<65535?f:n}function og(){try{if(Kt(at)){let t=If(at,"utf8"),n=JSON.parse(t);if(Array.isArray(n.engines)&&n.engines.length>0&&n.engines.every((f)=>typeof f==="string")){let f=n.engines.filter((g)=>wn[g]),p=n.engines.filter((g)=>!wn[g]);if(p.length>0)process.stderr.write(`[greedysearch] Warning: ignoring unknown engine(s) in ${at}: ${p.join(", ")}
352
+ [greedysearch] Available engines: ${Object.keys(wn).join(", ")}
353
+ `);if(f.length>0)return f;process.stderr.write(`[greedysearch] Warning: no valid engines in ${at}, falling back to defaults: ${jn.join(", ")}
354
+ `)}}}catch{}return jn}function Bg(){try{if(!Kt(vn))Vg(vn,{recursive:!0});if(!Kt(at))mg(at,JSON.stringify({engines:jn,synthesizer:Pn},null,2)+`
355
+ `,"utf8")}catch{}}function Ug(){try{if(Kt(at)){let t=If(at,"utf8"),n=JSON.parse(t);if(typeof n.synthesizer==="string"){let f=n.synthesizer.toLowerCase();if(Df.includes(f))return f;process.stderr.write(`[greedysearch] Warning: unknown synthesizer "${n.synthesizer}" in ${at}
356
+ [greedysearch] Available synthesizers: ${Df.join(", ")}
357
+ [greedysearch] Falling back to default: ${Pn}
358
+ `)}}}catch{}return Pn}function Qg(){if(typeof globalThis.DOMMatrix>"u")globalThis.DOMMatrix=class{constructor(t=void 0){}multiplySelf(){return this}preMultiplySelf(){return this}translateSelf(){return this}scaleSelf(){return this}rotateSelf(){return this}};if(typeof globalThis.ImageData>"u")globalThis.ImageData=class{constructor(t=void 0,n=0,f=0){this.data=t,this.width=n,this.height=f}};if(typeof globalThis.Path2D>"u")globalThis.Path2D=class{constructor(t=void 0){}}}async function xg(){Qg();let t=await import("pdf-parse"),n=t.PDFParse??t.default;if(!n)throw Error("pdf-parse did not export PDFParse");return n}async function zg(t,n){try{let f=new(await xg())({data:new Uint8Array(t)});await f.load();let p=await f.getText(),g=p.text?.trim();if(!g)return null;return{title:new URL(n).pathname.split("/").pop()||"Document.pdf",content:`## PDF Content (${p.total} pages)
359
+
360
+ ${g}`,pages:p.total}}catch(f){return{error:f.message||String(f)}}}function Ff(t="",n=240){let f=String(t).replaceAll(/\s+/g," ").trim();if(f.length<=n)return f;let p=f.slice(0,n),g=p.lastIndexOf(" ");return g>0?`${p.slice(0,g)}...`:`${p}...`}async function Sg(t,n,f=8000){let p=Date.now();try{let g=(await G(["evalraw",t,"Page.getFrameTree","{}"]).then((E)=>JSON.parse(E)).catch(()=>null))?.frameTree?.frame?.id||void 0,r=await G(["evalraw",t,"Network.loadNetworkResource",JSON.stringify({frameId:g,url:n,options:{disableCache:!0,includeCredentials:!1}})],20000),a=JSON.parse(r).resource;if(!a?.success||!a.httpStatusCode)return{url:n,error:a?.netErrorName||a?.netError||"loadNetworkResource failed",source:"chrome",duration:Date.now()-p,needsFallback:!0};let l="";if(a.stream)try{let E=await G(["evalraw",t,"IO.read",JSON.stringify({handle:a.stream})],1e4);l=JSON.parse(E).data||"",await G(["evalraw",t,"IO.close",JSON.stringify({handle:a.stream})]).catch(()=>{})}catch{}if(!l||l.length<100)return{url:n,error:"Empty response body from Network.loadNetworkResource",source:"chrome",duration:Date.now()-p,needsFallback:!0};let w=Pf(a.httpStatusCode,l,n,n);if(w.blocked)return{url:n,status:a.httpStatusCode,error:`Blocked: ${w.reason}`,source:"chrome",duration:Date.now()-p,needsBrowser:!0};let $=await Rf(l,n),_=yf($);if(!_.ok)return{url:n,status:a.httpStatusCode,error:`Low quality: ${_.reason}`,source:"chrome",duration:Date.now()-p,needsBrowser:!0};let e=Rt($.markdown,f);return{url:n,finalUrl:n,status:a.httpStatusCode,contentType:"text/markdown",lastModified:"",publishedTime:$.publishedTime||"",byline:$.byline||"",siteName:$.siteName||"",lang:$.lang||"",title:$.title||n,snippet:$.excerpt,content:e,contentChars:e.length,source:"chrome",duration:Date.now()-p}}catch(g){return{url:n,error:g.message,source:"chrome",duration:Date.now()-p,needsFallback:!0}}}function Gf(t){try{return new URL(t).pathname.toLowerCase().endsWith(".pdf")}catch{return!1}}async function cg(t,n=8000){let f=$n(t);if(f.blocked)return{url:t,finalUrl:t,status:403,error:`Blocked: ${f.reason}`,source:"pdf-http"};let p=new AbortController,g=setTimeout(()=>p.abort(),20000),r=Date.now();try{let a=await fetch(t,{method:"GET",redirect:"follow",signal:p.signal,headers:xp({accept:"application/pdf,application/octet-stream;q=0.9,*/*;q=0.5"})});clearTimeout(g);let l=a.headers.get("content-type")||"",w=a.url||t,$=Number.parseInt(a.headers.get("content-length")||"0",10);if(a.status>=400)return{url:t,finalUrl:w,status:a.status,error:`HTTP ${a.status}`,source:"pdf-http",duration:Date.now()-r};if(!l.toLowerCase().includes("application/pdf")&&!Gf(w))return null;if($>31457280)return{url:t,finalUrl:w,status:a.status,error:`PDF too large: ${$} bytes`,source:"pdf-http",duration:Date.now()-r};let _=Buffer.from(await a.arrayBuffer()),e=await zg(_,w);if(!e||e.error)return{url:t,finalUrl:w,status:a.status,error:e?.error||"PDF text extraction failed",source:"pdf-http",duration:Date.now()-r};let E=Rt(e.content,n);return{url:t,finalUrl:w,status:a.status,contentType:"application/pdf",lastModified:a.headers.get("last-modified")||"",title:e.title,snippet:Ff(E,320),content:E,contentChars:E.length,pages:e.pages,source:"pdf-http",duration:Date.now()-r}}catch(a){return clearTimeout(g),{url:t,finalUrl:t,error:a.message||String(a),source:"pdf-http",duration:Date.now()-r}}}async function Wf(t,n=8000){let f=Date.now();if(Gf(t)){let g=await cg(t,n);if(g?.content||g?.status===403)return g}if(_n(t)){let g=_n(t);if(g&&(g.type==="root"||g.type==="tree"||g.type==="blob"&&!g.path?.includes("."))){let r=await fg(t);if(r.ok){let a=Rt(r.content,n);return{url:t,finalUrl:t,status:200,contentType:"text/markdown",lastModified:"",title:r.title,snippet:a.slice(0,320),content:a,contentChars:a.length,source:"github-api",...r.tree&&{tree:r.tree},duration:Date.now()-f}}process.stderr.write(`[greedysearch] GitHub API fetch failed, trying HTTP: ${r.error}
361
+ `)}}if(gg(t)?.type==="post"){process.stderr.write(`[greedysearch] Using Reddit JSON API for: ${t.slice(0,60)}...
362
+ `);let g=await ag(t,n);if(g.ok){let r=Rt(g.markdown,n);return{url:t,finalUrl:g.finalUrl,status:g.status,contentType:"text/markdown",lastModified:g.lastModified||"",publishedTime:g.publishedTime||"",byline:g.byline||"",siteName:g.siteName||"",lang:g.lang||"",title:g.title,snippet:g.excerpt,content:r,contentChars:r.length,source:"reddit-api",duration:Date.now()-f}}process.stderr.write(`[greedysearch] Reddit API fetch failed, falling back to HTTP: ${g.error}
363
+ `)}let p=await Sp(t,{timeoutMs:1e4});if(p.ok){let g=Rt(p.markdown,n);return{url:t,finalUrl:p.finalUrl,status:p.status,contentType:"text/markdown",lastModified:p.lastModified||"",publishedTime:p.publishedTime||"",byline:p.byline||"",siteName:p.siteName||"",lang:p.lang||"",title:p.title,snippet:p.excerpt,content:g,contentChars:g.length,source:"http",duration:Date.now()-f}}if(p.needsBrowser)try{let g=await Rn();try{let r=await Sg(g,t,n);if(r.content&&r.content.length>100)return r}finally{await yn(g)}}catch{}return process.stderr.write(`[greedysearch] HTTP failed for ${t.slice(0,60)}, trying browser...
364
+ `),await dg(t,n)}async function Vf(t,n=4000,f=200){let p=Date.now()+n;while(Date.now()<p){try{if((await G(["eval",t,'document.readyState === "complete" && !!document.body && document.body.innerText.length > 500'])).trim()==="true")return}catch{}await new Promise((g)=>setTimeout(g,f))}}async function dg(t,n=8000){let f=Date.now(),p;try{p=await Rn()}catch(g){return{url:t,title:"",content:null,snippet:"",contentChars:0,error:`openNewTab failed: ${g.message}`,source:"browser",duration:Date.now()-f}}try{await G(["nav",p,t],30000),await Vf(p);let g=await G(["eval",p,String.raw`
280
365
  (function(){
281
366
  var el = document.querySelector('article, [role="main"], main, .post-content, .article-body, #content, .content');
282
367
  var text = (el || document.body).innerText;
@@ -286,106 +371,116 @@ ${a}`,pages:n.total}}catch(r){return{error:r.message||String(r)}}}function rr(t=
286
371
  url: location.href
287
372
  });
288
373
  })()
289
- `]),l=JSON.parse(a),i=q(l.content,e);return{url:t,finalUrl:l.url||t,status:200,contentType:"text/plain",lastModified:"",title:l.title,snippet:rr(i,320),content:i,contentChars:i.length,source:"browser",duration:Date.now()-r}}catch(a){return{url:t,title:"",content:null,snippet:"",contentChars:0,error:a.message,source:"browser",duration:Date.now()-r}}finally{await zt(n)}}async function ca(t,e=5,r=8000,n=Re){let a=t.slice(0,e);if(a.length===0)return[];let l=Math.min(a.length,Math.max(1,Number.parseInt(String(n),10)||Re));process.stderr.write(`[greedysearch] Fetching content from ${a.length} sources via HTTP (concurrency ${l})...
290
- `);let i=Array(a.length),f=0,o=0;async function g(){while(!0){let c=f++;if(c>=a.length)return;let y=a[c],b=y.canonicalUrl||y.url;process.stderr.write(`[greedysearch] [${c+1}/${a.length}] Fetching: ${b.slice(0,60)}...
291
- `);let w=await ar(b,r).catch((k)=>({url:b,title:"",content:null,snippet:"",contentChars:0,error:k.message,source:"error",duration:0}));if(i[c]={id:y.id,...w},w.content&&w.content.length>100)process.stderr.write(`[greedysearch] ✓ ${w.source}: ${w.content.length} chars
292
- `);else if(w.error)process.stderr.write(`[greedysearch] ✗ ${w.error.slice(0,80)}
293
- `);o+=1,process.stderr.write(`PROGRESS:fetch:${o}/${a.length}
294
- `)}}await Promise.all(Array.from({length:l},()=>g()));let p=i.filter((c)=>c.content&&c.content.length>100),h=i.filter((c)=>c.source==="http").length,m=i.filter((c)=>c.source==="browser").length;return process.stderr.write(`[greedysearch] Fetched ${p.length}/${i.length} sources (HTTP: ${h}, Browser: ${m})
295
- `),i}async function ma(t){let e=await Qt();await P(["list"]);try{await P(["nav",e,t],30000),await new Promise((n)=>setTimeout(n,800));let r=await P(["eval",e,String.raw`
374
+ `]),r=JSON.parse(g),a=Rt(r.content,n);return{url:t,finalUrl:r.url||t,status:200,contentType:"text/plain",lastModified:"",title:r.title,snippet:Ff(a,320),content:a,contentChars:a.length,source:"browser",duration:Date.now()-f}}catch(g){return{url:t,title:"",content:null,snippet:"",contentChars:0,error:g.message,source:"browser",duration:Date.now()-f}}finally{await yn(p)}}async function On(t,n=5,f=8000,p=bf){let g=t.slice(0,n);if(g.length===0)return[];let r=Math.min(g.length,Math.max(1,Number.parseInt(String(p),10)||bf));process.stderr.write(`[greedysearch] Fetching content from ${g.length} sources via HTTP (concurrency ${r})...
375
+ `);let a=Array(g.length),l=0,w=0;async function $(){while(!0){let h=l++;if(h>=g.length)return;let b=g[h],D=b.canonicalUrl||b.url;process.stderr.write(`[greedysearch] [${h+1}/${g.length}] Fetching: ${D.slice(0,60)}...
376
+ `);let v=await Wf(D,f).catch((P)=>({url:D,title:"",content:null,snippet:"",contentChars:0,error:P.message,source:"error",duration:0}));if(a[h]={id:b.id,...v},v.content&&v.content.length>100)process.stderr.write(`[greedysearch] ✓ ${v.source}: ${v.content.length} chars
377
+ `);else if(v.error)process.stderr.write(`[greedysearch] ✗ ${v.error.slice(0,80)}
378
+ `);w+=1,process.stderr.write(`PROGRESS:fetch:${w}/${g.length}
379
+ `)}}await Promise.all(Array.from({length:r},()=>$()));let _=a.filter((h)=>h.content&&h.content.length>100),e=a.filter((h)=>h.source==="http").length,E=a.filter((h)=>h.source==="browser").length;return process.stderr.write(`[greedysearch] Fetched ${_.length}/${a.length} sources (HTTP: ${e}, Browser: ${E})
380
+ `),a}async function qg(t){let n=await Rn();try{await G(["nav",n,t],30000),await Vf(n);let f=await G(["eval",n,String.raw`
296
381
  (function(){
297
382
  var el = document.querySelector('article, [role="main"], main, .post-content, .article-body, #content, .content');
298
383
  var text = (el || document.body).innerText;
299
384
  return text.replace(/\s+/g, ' ').trim();
300
385
  })()
301
- `]);return{url:t,content:r}}catch(r){return{url:t,content:null,error:r.message}}finally{await zt(e)}}var ii,Je,de="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",He,yn,vn,jn,Dn,Ze,Pn,Xn,xn,Qe,Ni,Ti,Oi,Pi,Gt,G,Vt,Zt="gemini",We,dt,Li,Wi,Mi,ze,Ai,Ri,Ji,di,Bt,V,Kt,Ut="gemini",Me,Ht,Hi,Fi,Yi,at,Gi,Vi,Zi,Bi,Ki,Ui,Ii,Se,Xi,xi,Qi,zi,P,er,ef,rf,nf,af,It,Z,Xt,xt="gemini",Ae,Ft,lf,ff,Re;var ir=gt(()=>{ii=$n(import.meta.url),Je=new bn({headingStyle:"atx",bulletListMarker:"-",codeBlockStyle:"fenced"});Je.addRule("removeDataUrls",{filter:(t)=>t.tagName==="IMG"&&t.getAttribute("src")?.startsWith("data:"),replacement:()=>""});He={"user-agent":de,accept:"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8","accept-language":"en-US,en;q=0.9","accept-encoding":"gzip, deflate, br","cache-control":"no-cache",pragma:"no-cache","sec-ch-ua":'"Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"',"sec-ch-ua-mobile":"?0","sec-ch-ua-platform":'"Windows"',"sec-fetch-dest":"document","sec-fetch-mode":"navigate","sec-fetch-site":"none","sec-fetch-user":"?1","upgrade-insecure-requests":"1"},yn=[/^localhost$/i,/^127\.\d+\.\d+\.\d+$/,/^0\.0\.0\.0$/,/^\[::1\]$/,/^10\./,/^172\.(1[6-9]|2\d|3[01])\./,/^192\.168\./,/^169\.254\./,/^fc00:/i,/^fe80:/i,/\.local$/i,/\.internal$/i,/\.localhost$/i];vn=["accounts.google.com","login.microsoftonline.com","login.live.com","auth0.com","okta.com","auth.mozilla.auth0.com","id.atlassian.com"],jn=["login.","signin.","auth.","sso.","accounts.","idp."],Dn=["sign in to continue","log in to continue","authentication required","create an account to continue","subscribe to continue reading","members only"];Ze={"user-agent":"GreedySearch/1.0",accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"};Pn={"user-agent":"GreedySearch/1.0 (Research Bot)",accept:"application/json"};Xn=Jn(Hn(import.meta.url)),xn=dn(Xn,"..","bin","cdp.mjs");Qe=`${_t().replaceAll("\\","/")}/greedysearch-chrome-profile`,Ni=`${Qe}/DevToolsActivePort`,Ti=`${_t().replaceAll("\\","/")}/cdp-pages.json`,Oi=`${_t().replaceAll("\\","/")}/greedysearch-chrome-mode`,Pi=`${_t().replaceAll("\\","/")}/greedysearch-visible-recovery.jsonl`,Gt=Ue(Vn(),".dm"),G=Ue(Gt,"greedyconfig"),Vt=["perplexity","google","chatgpt"];Sn();We=["gemini","chatgpt"];dt={perplexity:"perplexity.mjs",p:"perplexity.mjs",bing:"bing-copilot.mjs",b:"bing-copilot.mjs",google:"google-ai.mjs",g:"google-ai.mjs",gemini:"gemini.mjs",gem:"gemini.mjs",chatgpt:"chatgpt.mjs",gpt:"chatgpt.mjs","semantic-scholar":"semantic-scholar.mjs",semanticscholar:"semantic-scholar.mjs",s2:"semantic-scholar.mjs",logically:"logically.mjs",log:"logically.mjs"},Li=zn(),Wi=un(),Mi=Math.max(1,Number.parseInt(process.env.GREEDY_FETCH_CONCURRENCY||"5",10)||5);process.env.CDP_PROFILE_DIR=Qe;ze=`${kt().replaceAll("\\","/")}/greedysearch-chrome-profile`,Ai=`${ze}/DevToolsActivePort`,Ri=`${kt().replaceAll("\\","/")}/cdp-pages.json`,Ji=`${kt().replaceAll("\\","/")}/greedysearch-chrome-mode`,di=`${kt().replaceAll("\\","/")}/greedysearch-visible-recovery.jsonl`,Bt=Xe(Un(),".dm"),V=Xe(Bt,"greedyconfig"),Kt=["perplexity","google","chatgpt"];ta();Me=["gemini","chatgpt"];Ht={perplexity:"perplexity.mjs",p:"perplexity.mjs",bing:"bing-copilot.mjs",b:"bing-copilot.mjs",google:"google-ai.mjs",g:"google-ai.mjs",gemini:"gemini.mjs",gem:"gemini.mjs",chatgpt:"chatgpt.mjs",gpt:"chatgpt.mjs","semantic-scholar":"semantic-scholar.mjs",semanticscholar:"semantic-scholar.mjs",s2:"semantic-scholar.mjs",logically:"logically.mjs",log:"logically.mjs"},Hi=qn(),Fi=ea(),Yi=Math.max(1,Number.parseInt(process.env.GREEDY_FETCH_CONCURRENCY||"5",10)||5);process.env.CDP_PROFILE_DIR=ze;at=Zn().replaceAll("\\","/"),Gi=`${at}/greedysearch-chrome-metadata.json`,Vi=`${at}/greedysearch-chrome-launch.lock`,Zi=`${at}/greedysearch-chrome.pid`,Bi=`${at}/greedysearch-chrome-mode`,Ki=`${at}/greedysearch-chrome-last-activity`,Ui=Number.parseInt(process.env.GREEDY_SEARCH_IDLE_TIMEOUT_MINUTES||"5",10)||5,Ii=import.meta.dirname||new URL(".",import.meta.url).pathname.replace(/^\/([A-Z]:)/,"$1"),Se=An().replaceAll("\\","/"),Xi=`${Se}/greedysearch-chrome.pid`,xi=`${Se}/greedysearch-chrome-last-activity`,Qi=Number.parseInt(process.env.GREEDY_SEARCH_IDLE_TIMEOUT_MINUTES||"5",10)||5,zi=Number.parseInt(process.env.GREEDY_SEARCH_VISIBLE_IDLE_TIMEOUT_MINUTES||"60",10)||60,P=xe;er=`${st().replaceAll("\\","/")}/greedysearch-chrome-profile`,ef=`${er}/DevToolsActivePort`,rf=`${st().replaceAll("\\","/")}/cdp-pages.json`,nf=`${st().replaceAll("\\","/")}/greedysearch-chrome-mode`,af=`${st().replaceAll("\\","/")}/greedysearch-visible-recovery.jsonl`,It=tr(aa(),".dm"),Z=tr(It,"greedyconfig"),Xt=["perplexity","google","chatgpt"];ia();Ae=["gemini","chatgpt"];Ft={perplexity:"perplexity.mjs",p:"perplexity.mjs",bing:"bing-copilot.mjs",b:"bing-copilot.mjs",google:"google-ai.mjs",g:"google-ai.mjs",gemini:"gemini.mjs",gem:"gemini.mjs",chatgpt:"chatgpt.mjs",gpt:"chatgpt.mjs","semantic-scholar":"semantic-scholar.mjs",semanticscholar:"semantic-scholar.mjs",s2:"semantic-scholar.mjs",logically:"logically.mjs",log:"logically.mjs"},lf=la(),ff=fa(),Re=Math.max(1,Number.parseInt(process.env.GREEDY_FETCH_CONCURRENCY||"5",10)||5);process.env.CDP_PROFILE_DIR=er});var gr={};et(gr,{writeSourcesToFiles:()=>ka});import{mkdirSync as ba,writeFileSync as ya}from"node:fs";import{join as fr}from"node:path";function ka(t,e=_a){return ba(e,{recursive:!0}),t.map((r)=>{if(!r.content||r.content.length<10)return r;let n=String(r.id||"unknown").replace(/[^a-zA-Z0-9_-]/g,""),a=(r.canonicalUrl||r.url||"").replace(/^https?:\/\//,"").replace(/[^a-zA-Z0-9]/g,"-").slice(0,40),l=`${n}-${a}.md`,i=fr(e,l),f=`---
302
- url: ${r.finalUrl||r.url}
303
- title: ${r.title||""}
304
- source: ${r.source||"unknown"}
305
- status: ${r.status||""}
306
- chars: ${r.contentChars||r.content.length}
307
- ---
308
-
309
- `;ya(i,f+r.content,"utf8");let{content:o,...g}=r;return{...g,contentPath:i,contentChars:r.contentChars||o.length}})}var _a;var or=gt(()=>{_a=fr(process.cwd(),".dm","greedysearch-sources")});var St={};et(St,{parseGitHubUrl:()=>wr,fetchGitHubContent:()=>ja});function wr(t){try{let e=new URL(t);if(!(e.hostname==="github.com"||e.hostname.endsWith(".github.com")))return null;let r=e.pathname.split("/").filter(Boolean);if(r.length<2)return null;let[n,a]=r;if(r.length===2)return{owner:n,repo:a,type:"root"};if(r.length>=4&&(r[2]==="blob"||r[2]==="tree")){let l=r[2],i=r[3],f=r.slice(4).join("/");return{owner:n,repo:a,type:l,ref:i,path:f}}return null}catch{return null}}async function U(t,e=1e4){let r=new AbortController,n=setTimeout(()=>r.abort(),e);try{let a=await fetch(`https://api.github.com${t}`,{headers:hr,signal:r.signal});if(clearTimeout(n),!a.ok)throw Error(`GitHub API ${a.status}: ${t}`);return await a.json()}catch(a){throw clearTimeout(n),a}}async function sa(t,e){try{let r=await U(`/repos/${t}/${e}/readme`);if(r.content&&r.encoding==="base64")return Buffer.from(r.content,"base64").toString("utf8");return""}catch{return""}}async function pr(t,e,r="HEAD",n=""){try{let a=await U(`/repos/${t}/${e}/git/ref/heads/${r==="HEAD"?"main":r}`).catch(()=>U(`/repos/${t}/${e}/git/ref/heads/master`).catch(()=>null)),l;if(a?.object?.sha)l=(await U(`/repos/${t}/${e}/git/commits/${a.object.sha}`)).tree.sha;else{let f=await U(`/repos/${t}/${e}`);l=(await U(`/repos/${t}/${e}/branches/${f.default_branch}`)).commit.commit.tree.sha}let i=(await U(`/repos/${t}/${e}/git/trees/${l}`)).tree||[];if(n)i=i.filter((f)=>f.path.startsWith(n));return i.slice(0,50).map((f)=>({path:f.path,type:f.type==="tree"?"dir":"file",size:f.size}))}catch{return[]}}async function va(t,e,r,n,a=1e4){let l=[`https://raw.githubusercontent.com/${t}/${e}/${r&&r!=="HEAD"?r:"main"}/${n}`,`https://raw.githubusercontent.com/${t}/${e}/master/${n}`];for(let i of l){let f=new AbortController,o=setTimeout(()=>f.abort(),a);try{let g=await fetch(i,{headers:{"user-agent":hr["user-agent"]},signal:f.signal});if(clearTimeout(o),g.ok)return await g.text()}catch{clearTimeout(o)}}return null}async function ja(t){let e=wr(t);if(!e)return{ok:!1,error:"Not a valid GitHub URL"};let{owner:r,repo:n,type:a,ref:l,path:i}=e;try{if(a==="root"||a==="tree"&&!i){let[f,o,g]=await Promise.allSettled([U(`/repos/${r}/${n}`),sa(r,n),pr(r,n,l||"HEAD")]);if(f.status==="rejected")return{ok:!1,error:f.reason?.message||"Repo not found"};let p=f.value,h=o.status==="fulfilled"?o.value:"",m=g.status==="fulfilled"?g.value:[],c=p?.description?`
386
+ `]);return{url:t,content:f}}catch(f){return{url:t,content:null,error:f.message}}finally{await yn(n)}}var zr,cr,mt=null,Cf="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",vf,jf,Xp,op,Bp,cp,dp,qp,Of,pg,yg,Og,Ng,kg,wl,x,$l,_l,hl,el,El,Dl,bl,Cl,vl,hn,pt,en,En="gemini",ef,rn,jl,Pl,Rl,Mg,yl,z,Ol,Nl,il,Al,Tl,kl,Hl,Ll,Yl,Dn,gt,bn,Cn="gemini",Ef,ln,Il,Ml,Fl,Gl,Wl,Vl,ml,G,Xg,ol,S,Bl,Ul,Ql,xl,zl,Sl,cl,dl,ql,vn,at,jn,Pn="gemini",Df,wn,sl,ul,bf;var Xt=qt(()=>{zr=Jp(import.meta.url),cr=Zp(import.meta.url);vf={"user-agent":Cf,accept:"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8","accept-language":"en-US,en;q=0.9","accept-encoding":"gzip, deflate, br","cache-control":"no-cache",pragma:"no-cache","sec-ch-ua":'"Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"',"sec-ch-ua-mobile":"?0","sec-ch-ua-platform":'"Windows"',"sec-fetch-dest":"document","sec-fetch-mode":"navigate","sec-fetch-site":"none","sec-fetch-user":"?1","upgrade-insecure-requests":"1"},jf=[/^localhost$/i,/^127\.\d+\.\d+\.\d+$/,/^0\.0\.0\.0$/,/^\[::1\]$/,/^10\./,/^172\.(1[6-9]|2\d|3[01])\./,/^192\.168\./,/^169\.254\./,/^fc00:/i,/^fe80:/i,/\.local$/i,/\.internal$/i,/\.localhost$/i],Xp=/^::ffff:(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/i,op=/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i,Bp=/^(?:0x[0-9a-f]+|0[0-7]*|[1-9][0-9]*)$/i;cp=["accounts.google.com","login.microsoftonline.com","login.live.com","auth0.com","okta.com","auth.mozilla.auth0.com","id.atlassian.com"],dp=["login.","signin.","auth.","sso.","accounts.","idp."],qp=["sign in to continue","log in to continue","authentication required","create an account to continue","subscribe to continue reading","members only"];Of={"user-agent":"GreedySearch/1.0",accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"};pg={"user-agent":"GreedySearch/1.0 (Research Bot)",accept:"application/json"};yg=$g(hg(import.meta.url)),Og=_g(yg,"..","bin","cdp.mjs"),Ng=new Set(["list","snap","eval","shot","html","nav","net","click","clickxy","type","loadall","evalraw","browse","stop","--tab"]);kg=bg().replaceAll("\\","/"),wl=Tg(process.env.GREEDY_SEARCH_PORT),x=(process.env.GREEDY_SEARCH_PROFILE_DIR||process.env.CDP_PROFILE_DIR||`${kg}/greedysearch-chrome-profile`).replaceAll("\\","/"),$l=`${x}/DevToolsActivePort`,_l=process.env.GREEDY_SEARCH_PID_FILE||`${x}/browser.pid`,hl=process.env.CDP_PAGES_CACHE||`${x}/cdp-pages.json`,el=process.env.GREEDY_SEARCH_MODE_FILE||`${x}/browser-mode`,El=process.env.GREEDY_SEARCH_METADATA_FILE||`${x}/browser-metadata.json`,Dl=process.env.GREEDY_SEARCH_LAUNCH_LOCK_FILE||`${x}/browser-launch.lock`,bl=process.env.GREEDY_SEARCH_ACTIVITY_FILE||`${x}/browser-last-activity`,Cl=(process.env.CDP_SOCKET_DIR||`${x}/cdp-sockets`).replaceAll("\\","/"),vl=`${x}/visible-recovery.jsonl`,hn=Tf(Dg(),".dm"),pt=Tf(hn,"greedyconfig"),en=["perplexity","google","chatgpt","gemini"];Lg();ef=["gemini","chatgpt"];rn={perplexity:"perplexity.mjs",p:"perplexity.mjs",bing:"bing-copilot.mjs",b:"bing-copilot.mjs",google:"google-ai.mjs",g:"google-ai.mjs",gemini:"gemini.mjs",gem:"gemini.mjs",chatgpt:"chatgpt.mjs",gpt:"chatgpt.mjs","semantic-scholar":"semantic-scholar.mjs",semanticscholar:"semantic-scholar.mjs",s2:"semantic-scholar.mjs",logically:"logically.mjs",log:"logically.mjs"},jl=Hg(),Pl=Yg(),Rl=Math.max(1,Number.parseInt(process.env.GREEDY_FETCH_CONCURRENCY||"5",10)||5);process.env.CDP_PROFILE_DIR=x;Mg=Pg().replaceAll("\\","/"),yl=Ig(process.env.GREEDY_SEARCH_PORT),z=(process.env.GREEDY_SEARCH_PROFILE_DIR||process.env.CDP_PROFILE_DIR||`${Mg}/greedysearch-chrome-profile`).replaceAll("\\","/"),Ol=`${z}/DevToolsActivePort`,Nl=process.env.GREEDY_SEARCH_PID_FILE||`${z}/browser.pid`,il=process.env.CDP_PAGES_CACHE||`${z}/cdp-pages.json`,Al=process.env.GREEDY_SEARCH_MODE_FILE||`${z}/browser-mode`,Tl=process.env.GREEDY_SEARCH_METADATA_FILE||`${z}/browser-metadata.json`,kl=process.env.GREEDY_SEARCH_LAUNCH_LOCK_FILE||`${z}/browser-launch.lock`,Hl=process.env.GREEDY_SEARCH_ACTIVITY_FILE||`${z}/browser-last-activity`,Ll=(process.env.CDP_SOCKET_DIR||`${z}/cdp-sockets`).replaceAll("\\","/"),Yl=`${z}/visible-recovery.jsonl`,Dn=Hf(jg(),".dm"),gt=Hf(Dn,"greedyconfig"),bn=["perplexity","google","chatgpt","gemini"];Gg();Ef=["gemini","chatgpt"];ln={perplexity:"perplexity.mjs",p:"perplexity.mjs",bing:"bing-copilot.mjs",b:"bing-copilot.mjs",google:"google-ai.mjs",g:"google-ai.mjs",gemini:"gemini.mjs",gem:"gemini.mjs",chatgpt:"chatgpt.mjs",gpt:"chatgpt.mjs","semantic-scholar":"semantic-scholar.mjs",semanticscholar:"semantic-scholar.mjs",s2:"semantic-scholar.mjs",logically:"logically.mjs",log:"logically.mjs"},Il=Fg(),Ml=Wg(),Fl=Math.max(1,Number.parseInt(process.env.GREEDY_FETCH_CONCURRENCY||"5",10)||5);process.env.CDP_PROFILE_DIR=z;Gl=Number.parseInt(process.env.GREEDY_SEARCH_IDLE_TIMEOUT_MINUTES||"5",10)||5,Wl=import.meta.dirname||new URL(".",import.meta.url).pathname.replace(/^\/([A-Z]:)/,"$1"),Vl=Number.parseInt(process.env.GREEDY_SEARCH_IDLE_TIMEOUT_MINUTES||"5",10)||5,ml=Number.parseInt(process.env.GREEDY_SEARCH_VISIBLE_IDLE_TIMEOUT_MINUTES||"60",10)||60,G=Lf;Xg=Zg().replaceAll("\\","/"),ol=Kg(process.env.GREEDY_SEARCH_PORT),S=(process.env.GREEDY_SEARCH_PROFILE_DIR||process.env.CDP_PROFILE_DIR||`${Xg}/greedysearch-chrome-profile`).replaceAll("\\","/"),Bl=`${S}/DevToolsActivePort`,Ul=process.env.GREEDY_SEARCH_PID_FILE||`${S}/browser.pid`,Ql=process.env.CDP_PAGES_CACHE||`${S}/cdp-pages.json`,xl=process.env.GREEDY_SEARCH_MODE_FILE||`${S}/browser-mode`,zl=process.env.GREEDY_SEARCH_METADATA_FILE||`${S}/browser-metadata.json`,Sl=process.env.GREEDY_SEARCH_LAUNCH_LOCK_FILE||`${S}/browser-launch.lock`,cl=process.env.GREEDY_SEARCH_ACTIVITY_FILE||`${S}/browser-last-activity`,dl=(process.env.CDP_SOCKET_DIR||`${S}/cdp-sockets`).replaceAll("\\","/"),ql=`${S}/visible-recovery.jsonl`,vn=Mf(Jg(),".dm"),at=Mf(vn,"greedyconfig"),jn=["perplexity","google","chatgpt","gemini"];Bg();Df=["gemini","chatgpt"];wn={perplexity:"perplexity.mjs",p:"perplexity.mjs",bing:"bing-copilot.mjs",b:"bing-copilot.mjs",google:"google-ai.mjs",g:"google-ai.mjs",gemini:"gemini.mjs",gem:"gemini.mjs",chatgpt:"chatgpt.mjs",gpt:"chatgpt.mjs","semantic-scholar":"semantic-scholar.mjs",semanticscholar:"semantic-scholar.mjs",s2:"semantic-scholar.mjs",logically:"logically.mjs",log:"logically.mjs"},sl=og(),ul=Ug(),bf=Math.max(1,Number.parseInt(process.env.GREEDY_FETCH_CONCURRENCY||"5",10)||5);process.env.CDP_PROFILE_DIR=S});var Bf={};dt(Bf,{parseGitHubUrl:()=>of,fetchGitHubContent:()=>ba});function of(t){try{let n=new URL(t);if(!(n.hostname==="github.com"||n.hostname.endsWith(".github.com")))return null;let f=n.pathname.split("/").filter(Boolean);if(f.length<2)return null;let[p,g]=f;if(f.length===2)return{owner:p,repo:g,type:"root"};if(f.length>=4&&(f[2]==="blob"||f[2]==="tree")){let r=f[2],a=f[3],l=f.slice(4).join("/");return{owner:p,repo:g,type:r,ref:a,path:l}}return null}catch{return null}}async function U(t,n=1e4){let f=new AbortController,p=setTimeout(()=>f.abort(),n);try{let g=await fetch(`https://api.github.com${t}`,{headers:Xf,signal:f.signal});if(clearTimeout(p),!g.ok)throw Error(`GitHub API ${g.status}: ${t}`);return await g.json()}catch(g){throw clearTimeout(p),g}}async function Ea(t,n){try{let f=await U(`/repos/${t}/${n}/readme`);if(f.content&&f.encoding==="base64")return Buffer.from(f.content,"base64").toString("utf8");return""}catch{return""}}async function Kf(t,n,f="HEAD",p="",g){try{let r;if(f==="HEAD")if(g)r=await U(`/repos/${t}/${n}/git/ref/heads/${g}`).catch(()=>null);else r=await Promise.any([U(`/repos/${t}/${n}/git/ref/heads/main`),U(`/repos/${t}/${n}/git/ref/heads/master`)]).catch(()=>null);else r=await U(`/repos/${t}/${n}/git/ref/heads/${f}`).catch(()=>U(`/repos/${t}/${n}/git/ref/heads/master`).catch(()=>null));if(!r?.object?.sha)return[];let a=(await U(`/repos/${t}/${n}/git/commits/${r.object.sha}`)).tree.sha,l=(await U(`/repos/${t}/${n}/git/trees/${a}`)).tree||[];if(p)l=l.filter((w)=>w.path.startsWith(p));return l.slice(0,50).map((w)=>({path:w.path,type:w.type==="tree"?"dir":"file",size:w.size}))}catch{return[]}}async function Da(t,n,f,p,g=1e4,r){let a=async(w)=>{let $=new AbortController,_=setTimeout(()=>$.abort(),g);try{let e=await fetch(w,{headers:{"user-agent":Xf["user-agent"]},signal:$.signal});if(clearTimeout(_),e.ok)return await e.text();throw Error("not ok")}catch{throw clearTimeout(_),Error("failed")}};if(!f||f==="HEAD"){if(r)try{return await a(`https://raw.githubusercontent.com/${t}/${n}/${r}/${p}`)}catch{return null}try{return await Promise.any([a(`https://raw.githubusercontent.com/${t}/${n}/main/${p}`),a(`https://raw.githubusercontent.com/${t}/${n}/master/${p}`)])}catch{return null}}let l=[`https://raw.githubusercontent.com/${t}/${n}/${f}/${p}`,`https://raw.githubusercontent.com/${t}/${n}/master/${p}`];for(let w of l)try{return await a(w)}catch{}return null}async function ba(t){let n=of(t);if(!n)return{ok:!1,error:"Not a valid GitHub URL"};let{owner:f,repo:p,type:g,ref:r,path:a}=n;try{if(g==="root"||g==="tree"&&!a){let l=await U(`/repos/${f}/${p}`),[w,$]=await Promise.allSettled([Ea(f,p),Kf(f,p,r||"HEAD","",l.default_branch)]),_=w.status==="fulfilled"?w.value:"",e=$.status==="fulfilled"?$.value:[],E=l?.description?`
310
387
 
311
- > ${p.description}`:"",y=p?.stargazers_count==null?"":` ⭐ ${p.stargazers_count}`,b=p?.language?` · ${p.language}`:"",w=`# ${r}/${n}${y}${b}${c}
388
+ > ${l.description}`:"",h=l?.stargazers_count==null?"":` ⭐ ${l.stargazers_count}`,b=l?.language?` · ${l.language}`:"",D=`# ${f}/${p}${h}${b}${E}
312
389
 
313
- `;if(h)w+=h.slice(0,6000);else w+=`[No README found]
390
+ `;if(_)D+=_.slice(0,6000);else D+=`[No README found]
314
391
 
315
392
  Files:
316
- ${m.map((k)=>` ${k.type==="dir"?"\uD83D\uDCC1":"\uD83D\uDCC4"} ${k.path}`).join(`
317
- `)}`;return{ok:!0,title:`${r}/${n}`,content:w,tree:m.slice(0,30)}}if(a==="blob"&&i){let f=await va(r,n,l,i);if(f===null)return{ok:!1,error:`File not found: ${i}`};return{ok:!0,title:`${r}/${n}: ${i}`,content:f}}if(a==="tree"&&i){let f=await pr(r,n,l||"HEAD",i),o=f.map((g)=>` ${g.type==="dir"?"\uD83D\uDCC1":"\uD83D\uDCC4"} ${g.path}`).join(`
318
- `);return{ok:!0,title:`${r}/${n}/${i}`,content:`[Directory: ${i}]
393
+ ${e.map((v)=>` ${v.type==="dir"?"\uD83D\uDCC1":"\uD83D\uDCC4"} ${v.path}`).join(`
394
+ `)}`;return{ok:!0,title:`${f}/${p}`,content:D,tree:e.slice(0,30)}}if(g==="blob"&&a){let l;if(!r||r==="HEAD")try{l=(await U(`/repos/${f}/${p}`)).default_branch}catch{l=void 0}let w=await Da(f,p,r,a,1e4,l);if(w===null)return{ok:!1,error:`File not found: ${a}`};return{ok:!0,title:`${f}/${p}: ${a}`,content:w}}if(g==="tree"&&a){let l;if(!r||r==="HEAD")try{l=(await U(`/repos/${f}/${p}`)).default_branch}catch{l=void 0}let w=await Kf(f,p,r||"HEAD",a,l),$=w.map((_)=>` ${_.type==="dir"?"\uD83D\uDCC1":"\uD83D\uDCC4"} ${_.path}`).join(`
395
+ `);return{ok:!0,title:`${f}/${p}/${a}`,content:`[Directory: ${a}]
319
396
 
320
397
  Files:
321
- ${o}`,tree:f}}return{ok:!1,error:"Unsupported GitHub URL type"}}catch(f){return{ok:!1,error:f.message}}}var hr;var ut=gt(()=>{hr={"user-agent":"GreedySearch/1.0",accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});var qt={};et(qt,{truncateContent:()=>Ca,trimContentHeadTail:()=>Ea});function Ea(t,e=8000){if(!t||t.length<=e)return t;let r=`
322
-
323
- [...content trimmed...]
324
-
325
- `,n=e-r.length,a=Math.floor(n*0.75),l=n-a,i=a;while(i>a-100&&t[i]!==`
326
- `)i--;if(i<=a-100)i=a;let f=t.length-l;while(f<t.length-l+100&&t[f]!==`
327
- `)f++;if(f>=t.length-l+100)f=t.length-l;let o=t.slice(0,i).trimEnd(),g=t.slice(f).trimStart();return`${o}${r}${g}`}function Ca(t,e=8000){if(!t||t.length<=e)return t;let r=t.slice(0,e),n=r.lastIndexOf(" ");return n>0?`${r.slice(0,n)}...`:`${r}...`}var jr={};et(jr,{shouldUseBrowser:()=>Ha,rewriteGitHubUrl:()=>_r,isPrivateUrl:()=>yr,fetchSourceHttp:()=>Wa,extractContent:()=>sr,detectBotBlock:()=>kr,defaultFetchHeaders:()=>La,checkContentQuality:()=>vr});import{Readability as Na}from"@mozilla/readability";import{JSDOM as Ta}from"jsdom";import Oa from"turndown";function La(t={}){return{...br,...t}}function yr(t){try{let e=new URL(t),r=e.hostname.toLowerCase();for(let n of Pa)if(n.test(r))return{blocked:!0,reason:`Private/internal address: ${r}`};if(e.protocol==="file:")return{blocked:!0,reason:"File protocol not allowed"};return{blocked:!1}}catch(e){return{blocked:!0,reason:`Invalid URL: ${e.message}`}}}function _r(t){try{let e=new URL(t);if(!(e.hostname==="github.com"||e.hostname.endsWith(".github.com")))return t;let r=e.pathname.split("/").filter(Boolean);if(r.length<5)return t;let[n,a,l,i,...f]=r;if(l!=="blob")return t;let o=f.join("/");return`https://raw.githubusercontent.com/${n}/${a}/${i}/${o}`}catch{return t}}async function Wa(t,e={}){let r=yr(t);if(r.blocked)return{ok:!1,url:t,finalUrl:t,status:403,error:`Blocked: ${r.reason}`,needsBrowser:!1};let n=t;if(t=_r(t),t!==n)console.error(`[fetcher] Rewrote GitHub URL: ${n.slice(0,60)}... → raw.githubusercontent.com`);let{timeoutMs:a=15000,userAgent:l,signal:i}=e,f=new AbortController,o=setTimeout(()=>f.abort(),a);if(i)i.addEventListener("abort",()=>f.abort(),{once:!0});try{let g=await fetch(t,{method:"GET",headers:{...br,"user-agent":l||mr},redirect:"follow",signal:f.signal});clearTimeout(o);let p=g.headers.get("content-type")||"",h=g.url,m=g.headers.get("last-modified")||"",c=!1;try{c=new URL(h).hostname.toLowerCase()==="raw.githubusercontent.com"}catch{}if(p.includes("text/plain")&&c){let C=await g.text();return{ok:!0,url:n,finalUrl:h,status:g.status,title:h.split("/").pop()||"GitHub File",byline:"",siteName:"GitHub",lang:"",publishedTime:m,lastModified:m,markdown:C,contentLength:C.length,excerpt:C.slice(0,300).replaceAll(/\n/g," "),needsBrowser:!1}}if(!p.includes("text/html")&&!p.includes("application/xhtml"))return{ok:!1,url:t,finalUrl:h,status:g.status,error:`Unsupported content type: ${p}`,needsBrowser:!1};let y=await g.text(),b=kr(g.status,y,h,t);if(b.blocked)return{ok:!1,url:t,finalUrl:h,status:g.status,error:`Blocked: ${b.reason}`,needsBrowser:!0};let w=sr(y,h),k=vr(w);if(!k.ok)return{ok:!1,url:t,finalUrl:h,status:g.status,error:`Low quality content: ${k.reason}`,needsBrowser:!0};return{ok:!0,url:t,finalUrl:h,status:g.status,title:w.title,byline:w.byline,siteName:w.siteName,lang:w.lang,publishedTime:w.publishedTime||m,lastModified:m,markdown:w.markdown,excerpt:w.excerpt,contentLength:w.markdown.length,needsBrowser:!1}}catch(g){clearTimeout(o);let p=da(g);return{ok:!1,url:t,finalUrl:t,status:0,error:g.message,needsBrowser:p}}}function kr(t,e,r,n){let a=e.match(/<title[^>]*>([^<]*)<\/title>/i)?.[1]?.toLowerCase()||"",l=e.slice(0,30000).toLowerCase(),i=`${a} ${l}`;if(t===403||t===429||t===503)return{blocked:!0,reason:`HTTP ${t}`};let f=[{pattern:/class=["'][^"']*captcha["']|<div[^>]*id=["']captcha/i,reason:"captcha"},{pattern:/g-recaptcha|data-sitekey|i['"]m not a robot/i,reason:"captcha"},{pattern:/checking your browser.{0,100}please wait|cf-browser-verification/i,reason:"cloudflare challenge"},{pattern:/just a moment.{0,50}security check|ddos protection by cloudflare/i,reason:"cloudflare challenge"},{pattern:/unusual traffic.{0,50}from your computer network/i,reason:"unusual traffic"},{pattern:/bot detected|automated.{0,20}request/i,reason:"bot detection"},{pattern:/enable\s+javascript\s+to\s+view|javascript\s+is\s+required.{0,50}enabled/i,reason:"requires javascript"},{pattern:/access denied|accessdenied/i,reason:"access denied"},{pattern:/protected by anubis|anubis uses a proof-of-work/i,reason:"anubis challenge"}];for(let g of f)if(g.pattern.test(i))return{blocked:!0,reason:g.reason};let o=Ja(n,r,e);if(o)return{blocked:!0,reason:o};return{blocked:!1}}function Ja(t,e,r){try{let n=new URL(t),a=new URL(e);if(n.hostname.toLowerCase()===a.hostname.toLowerCase())return;let l=a.hostname.toLowerCase();if(Ma.some((f)=>l===f||l.endsWith(`.${f}`)))return`redirected to login (${a.hostname})`;if(Aa.some((f)=>l.startsWith(f)))return`redirected to login (${a.hostname})`;let i=r.slice(0,20000).toLowerCase();if(Ra.some((f)=>i.includes(f)))return`redirected to login page (${a.hostname})`}catch{}return}function da(t){let e=t.message.toLowerCase();return e.includes("fetch failed")||e.includes("unable to verify")||e.includes("certificate")||e.includes("timeout")}function $r(t){let e=['meta[property="article:published_time"]','meta[name="article:published_time"]','meta[property="og:published_time"]','meta[name="publication_date"]','meta[name="date"]','meta[itemprop="datePublished"]','time[itemprop="datePublished"]','meta[name="DC.date"]'];for(let r of e){let n=t.querySelector(r),a=n?.getAttribute("content")||n?.getAttribute("datetime")||"";if(a)return a}return""}function sr(t,e){let r=new Ta(t,{url:e}).window.document,n=new Na(r).parse();if(n&&n.content){let l=cr.turndown(n.content).replaceAll(/\n{3,}/g,`
328
-
329
- `).trim(),i=n.publishedTime||$r(r)||"";return{title:n.title||r.title||e,byline:n.byline||"",siteName:n.siteName||"",lang:n.lang||"",publishedTime:i,markdown:l,excerpt:l.slice(0,300).replaceAll(/\n/g," ")}}let a=r.body;if(a){let l=a.cloneNode(!0);l.querySelectorAll("script, style, nav, footer, header, aside").forEach((f)=>f.remove());let i=(l.textContent||"").replaceAll(/\s+/g," ").trim();return{title:r.title||e,byline:"",siteName:"",lang:"",publishedTime:$r(r),markdown:i,excerpt:i.slice(0,300)}}return{title:e,byline:"",siteName:"",lang:"",publishedTime:"",markdown:"",excerpt:""}}function vr(t){let e=t.markdown.trim().toLowerCase(),r=(t.title||"").toLowerCase();if(t.markdown.trim().length<100)return{ok:!1,reason:"content too short (< 100 chars)"};let n=e.toLowerCase(),a=[{check:()=>n.includes("loading")&&n.includes("please wait"),desc:"loading page"},{check:()=>n.includes("please ensure javascript is enabled"),desc:"requires javascript"},{check:()=>n.includes("enable javascript to view"),desc:"requires javascript"},{check:()=>n.includes("just a moment"),desc:"cloudflare challenge detected in content"},{check:()=>n.includes("verify you are human"),desc:"human verification"},{check:()=>n.includes("captcha required"),desc:"captcha in extracted content"},{check:()=>n.includes("access denied"),desc:"access denied in content"},{check:()=>/^\s{0,10}sign\s{1,5}in\s{0,10}$|^\s{0,10}log\s{1,5}in\s{0,10}$/im.test(e),desc:"login form only"}];for(let{check:l,desc:i}of a)if(l())return{ok:!1,reason:i};if(r.includes("just a moment")||r.includes("checking your browser"))return{ok:!1,reason:"cloudflare challenge page detected in title"};return{ok:!0}}function Ha(t){try{let e=new URL(t),r=e.hostname.toLowerCase(),n=e.pathname.toLowerCase();if(["react.dev","nextjs.org","vuejs.org","angular.io","svelte.dev","docs.expo.dev","tailwindcss.com","storybook.js.org"].some((a)=>r===a||r.endsWith(`.${a}`)))return!0;if(n.includes("/playground")||n.includes("/demo")||n.includes("/app"))return!0;if(e.hash&&e.hash.length>1)return!0;return!1}catch{return!1}}var cr,mr="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",br,Pa,Ma,Aa,Ra;var Dr=gt(()=>{cr=new Oa({headingStyle:"atx",bulletListMarker:"-",codeBlockStyle:"fenced"});cr.addRule("removeDataUrls",{filter:(t)=>t.tagName==="IMG"&&t.getAttribute("src")?.startsWith("data:"),replacement:()=>""});br={"user-agent":mr,accept:"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8","accept-language":"en-US,en;q=0.9","accept-encoding":"gzip, deflate, br","cache-control":"no-cache",pragma:"no-cache","sec-ch-ua":'"Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"',"sec-ch-ua-mobile":"?0","sec-ch-ua-platform":'"Windows"',"sec-fetch-dest":"document","sec-fetch-mode":"navigate","sec-fetch-site":"none","sec-fetch-user":"?1","upgrade-insecure-requests":"1"},Pa=[/^localhost$/i,/^127\.\d+\.\d+\.\d+$/,/^0\.0\.0\.0$/,/^\[::1\]$/,/^10\./,/^172\.(1[6-9]|2\d|3[01])\./,/^192\.168\./,/^169\.254\./,/^fc00:/i,/^fe80:/i,/\.local$/i,/\.internal$/i,/\.localhost$/i];Ma=["accounts.google.com","login.microsoftonline.com","login.live.com","auth0.com","okta.com","auth.mozilla.auth0.com","id.atlassian.com"],Aa=["login.","signin.","auth.","sso.","accounts.","idp."],Ra=["sign in to continue","log in to continue","authentication required","create an account to continue","subscribe to continue reading","members only"]});import{spawn as Fa}from"node:child_process";import{mkdirSync as te,writeFileSync as W}from"node:fs";import{join as E}from"node:path";import{fileURLToPath as Ya}from"node:url";var Zr=["fbclid","gclid","ref","ref_src","ref_url","source","utm_campaign","utm_content","utm_medium","utm_source","utm_term"],Br=["dev.to","hashnode.com","medium.com","reddit.com","stackoverflow.com","stackexchange.com","substack.com"],Kr=["arstechnica.com","techcrunch.com","theverge.com","venturebeat.com","wired.com","zdnet.com"],ke=["facebook.com","instagram.com","linkedin.com","pinterest.com","tiktok.com","twitter.com","x.com"];function T(t="",e=240){let r=String(t).replaceAll(/\s+/g," ").trim();if(r.length<=e)return r;let n=r.slice(0,e),a=n.lastIndexOf(" ");return a>0?`${n.slice(0,a)}...`:`${n}...`}function Tt(t=""){let e=T(t,180);if(!e)return"";if(/^https?:\/\//i.test(e))return"";let r=e.split(/\s+/).filter(Boolean).length,n=/[A-Z]/.test(e),a=/\d/.test(e);return e===e.toLowerCase()&&r<=4&&!n&&!a?"":e}function Ot(t="",e=""){let r=Tt(t),n=Tt(e);if(!n)return r;if(!r)return n;let a=/^https?:\/\//i.test(r),l=/^https?:\/\//i.test(n);if(a&&!l)return n;if(!a&&l)return r;return n.length>r.length?n:r}function M(t){if(!t)return null;try{let e=new URL(t);if(!["http:","https:"].includes(e.protocol))return null;if(e.hash="",e.hostname=e.hostname.toLowerCase(),e.protocol==="https:"&&e.port==="443"||e.protocol==="http:"&&e.port==="80")e.port="";for(let a of[...e.searchParams.keys()]){let l=a.toLowerCase();if(Zr.includes(l)||l.startsWith("utm_"))e.searchParams.delete(a)}e.searchParams.sort();let r=e.pathname.replace(/\/{1,10}$/,"")||"/";e.pathname=r;let n=e.toString();return r==="/"?n.replace(/\/$/,""):n}catch{return null}}function Ur(t){try{return new URL(t).hostname.toLowerCase().replace(/^www\./,"")}catch{return""}}function rt(t,e){return e.some((r)=>t===r||t.endsWith(`.${r}`))}function Pt(t,e="",r=""){let n=e.toLowerCase(),a=r.toLowerCase();if(t==="github.com"||t==="gitlab.com")return"repo";if(t==="arxiv.org"||t==="doi.org"||t==="semanticscholar.org"||t.endsWith(".semanticscholar.org")||a.includes("/paper/")||a.includes("/pdf/"))return"academic";if(rt(t,ke))return"social";if(rt(t,Br))return"community";if(rt(t,Kr))return"news";if(t.startsWith("docs.")||t.startsWith("developer.")||t.startsWith("developers.")||t.startsWith("api.")||n.includes("documentation")||n.includes("docs")||n.includes("reference")||a.includes("/docs/")||a.includes("/reference/")||a.includes("/api/"))return"official-docs";if(t.startsWith("blog.")||a.includes("/blog/"))return"maintainer-blog";return"website"}function Ir(t){switch(t){case"official-docs":return 5;case"repo":return 4;case"academic":return 4;case"maintainer-blog":return 3;case"website":return 2;case"community":return 1;case"news":return 0;case"social":return-6;default:return 0}}function Xr(t){let e=Object.values(t.perEngine||{}).map((r)=>r?.rank||99);return e.length?Math.min(...e):99}var xr=["reddit.com","news.ycombinator.com","lobste.rs"];function X(t){return t.smartScore*3+t.engineCount*5+Ir(t.sourceType)*2+Math.max(0,7-Xr(t))}function Qr(t){let e=t.toLowerCase(),r=[];if(e.includes("openai")||e.includes("gpt")||e.includes("chatgpt"))r.push("openai.com","platform.openai.com","help.openai.com");if(e.includes("anthropic")||e.includes("claude"))r.push("anthropic.com","docs.anthropic.com");if(e.includes("bun"))r.push("bun.sh","bun.com");if(e.includes("next.js")||e.includes("nextjs"))r.push("nextjs.org","vercel.com");if(e.includes("playwright"))r.push("playwright.dev");if(e.includes("supabase"))r.push("supabase.com","supabase.io");if(e.includes("prisma"))r.push("prisma.io");if(e.includes("tailwind"))r.push("tailwindcss.com");if(e.includes("vite"))r.push("vitejs.dev","vite.dev");if(e.includes("astro"))r.push("astro.build");if(e.includes("svelte"))r.push("svelte.dev");if(e.includes("solid"))r.push("solidjs.com");if(e.includes("vue")||e.includes("nuxt"))r.push("vuejs.org","nuxt.com");if(e.includes("react")||e.includes("react native"))r.push("react.dev","reactnative.dev");if(e.includes("angular"))r.push("angular.io","angular.dev");if(e.includes("node.js")||e.includes("nodejs"))r.push("nodejs.org","nodejs.dev","npmjs.com");if(/\bgo\b/.test(e)||e.includes("golang"))r.push("go.dev","golang.org","pkg.go.dev");if(e.includes("deno"))r.push("deno.land","deno.com");if(e.includes("fresh"))r.push("fresh.deno.dev");if(e.includes("typescript")||e.includes("ts"))r.push("typescriptlang.org");if(e.includes("python"))r.push("python.org","docs.python.org");if(e.includes("rust"))r.push("rust-lang.org","docs.rs","crates.io");if(e.includes("zig"))r.push("ziglang.org");if(e.includes("docker"))r.push("docker.com","docs.docker.com","hub.docker.com");if(e.includes("kubernetes")||e.includes("k8s"))r.push("kubernetes.io","k8s.io");if(e.includes("postgres")||e.includes("postgresql"))r.push("postgresql.org","neon.tech","supabase.com");if(e.includes("redis"))r.push("redis.io");if(e.includes("sqlite"))r.push("sqlite.org");if(e.includes("cloudflare"))r.push("developers.cloudflare.com","cloudflare.com");if(e.includes("vercel"))r.push("vercel.com","nextjs.org");if(e.includes("netlify"))r.push("netlify.com","docs.netlify.com");if(e.includes("stripe"))r.push("stripe.com","docs.stripe.com");if(e.includes("github"))r.push("github.com","docs.github.com");if(e.includes("gitlab"))r.push("gitlab.com","docs.gitlab.com");if(e.includes("aws"))r.push("aws.amazon.com","docs.aws.amazon.com");if(e.includes("azure"))r.push("azure.microsoft.com","learn.microsoft.com");if(e.includes("gcp")||e.includes("google cloud"))r.push("cloud.google.com","developers.google.com");if(e.includes("gemini")||e.includes("google ai"))r.push("ai.google.dev","developers.google.com");for(let n of ke){let a=n.replace(/\.com$/,"");if(e.includes(a))r.push(n)}return[...new Set(r)]}function _e(t,e){return t===e||t.endsWith(`.${e}`)}function Lt(t,e=""){let r=new Map,n=Object.keys(t||{}).filter((g)=>!g.startsWith("_")),a=Qr(e);for(let g of n){let p=t[g];if(!p?.sources)continue;for(let h=0;h<p.sources.length;h++){let m=p.sources[h],c=M(m.url);if(!c||c.length<10)continue;let y=Tt(m.title||""),b=Ur(c),w=Pt(b,y,c),k=0;if(a.some((N)=>_e(b,N)))k+=10;if(w==="official-docs")k+=3;let C=c.toLowerCase();if(/\/docs\/|\/documentation\/|\.dev\/|\/api\/|\/reference\//.test(C))k+=2;let _=a.some((N)=>_e(b,N));if(w==="social"&&!_)k-=20;if(a.length>0){if(rt(b,xr))k-=3;else if(w==="community"&&!rt(b,["stackoverflow.com","stackexchange.com"]))k-=1}let s=r.get(c)||{id:"",canonicalUrl:c,displayUrl:m.url||c,domain:b,title:"",engines:[],engineCount:0,perEngine:{},sourceType:w,isOfficial:w==="official-docs",smartScore:0};if(s.title=Ot(s.title,y),s.displayUrl=s.displayUrl||m.url||c,s.sourceType=s.sourceType||w,s.isOfficial=s.isOfficial||w==="official-docs",s.smartScore=Math.max(s.smartScore,k),!s.engines.includes(g))s.engines.push(g);s.perEngine[g]={rank:h+1,title:Ot(s.perEngine[g]?.title||"",y)},r.set(c,s)}}let l=Array.from(r.values()).map((g)=>({...g,engineCount:g.engines.length})),i=l.filter((g)=>g.sourceType!=="social"),f=l.filter((g)=>g.sourceType==="social");return i.sort((g,p)=>{let h=X(p)-X(g);if(h!==0)return h;return g.domain.localeCompare(p.domain)}),f.sort((g,p)=>{let h=X(p)-X(g);if(h!==0)return h;return g.domain.localeCompare(p.domain)}),[...i,...f].slice(0,12).map((g,p)=>({...g,id:`S${p+1}`,title:g.title||g.domain||g.canonicalUrl}))}function se(t,e){let r=new Map(e.map((n)=>[n.id,n]));return t.map((n)=>{let a=r.get(n.id);if(!a)return n;let l=Ot(n.title,a.title||"");return{...n,title:l||n.title,fetch:{attempted:!0,ok:!a.error&&a.contentChars>100,status:a.status||null,finalUrl:a.finalUrl||a.url||n.canonicalUrl,contentType:a.contentType||"",lastModified:a.lastModified||"",publishedTime:a.publishedTime||"",byline:a.byline||"",siteName:a.siteName||"",lang:a.lang||"",title:a.title||"",snippet:a.snippet||"",contentChars:a.contentChars||0,source:a.source||"unknown",duration:a.duration||0,error:a.error||""}}})}import{existsSync as ot,mkdirSync as zr,readFileSync as ve,writeFileSync as Sr}from"node:fs";import{homedir as ur}from"node:os";import{join as je}from"node:path";import{tmpdir as pt}from"node:os";var ht=`${pt().replaceAll("\\","/")}/greedysearch-chrome-profile`,Rl=`${ht}/DevToolsActivePort`,Jl=`${pt().replaceAll("\\","/")}/cdp-pages.json`,dl=`${pt().replaceAll("\\","/")}/greedysearch-chrome-mode`,Hl=`${pt().replaceAll("\\","/")}/greedysearch-visible-recovery.jsonl`,Mt=je(ur(),".dm"),Y=je(Mt,"greedyconfig"),At=["perplexity","google","chatgpt"],Rt="gemini";function qr(){try{if(ot(Y)){let t=ve(Y,"utf8"),e=JSON.parse(t);if(Array.isArray(e.engines)&&e.engines.length>0&&e.engines.every((r)=>typeof r==="string")){let r=e.engines.filter((a)=>Wt[a]),n=e.engines.filter((a)=>!Wt[a]);if(n.length>0)process.stderr.write(`[greedysearch] Warning: ignoring unknown engine(s) in ${Y}: ${n.join(", ")}
330
- [greedysearch] Available engines: ${Object.keys(Wt).join(", ")}
331
- `);if(r.length>0)return r;process.stderr.write(`[greedysearch] Warning: no valid engines in ${Y}, falling back to defaults: ${At.join(", ")}
332
- `)}}}catch{}return At}function tn(){try{if(!ot(Mt))zr(Mt,{recursive:!0});if(!ot(Y))Sr(Y,JSON.stringify({engines:At,synthesizer:Rt},null,2)+`
333
- `,"utf8")}catch{}}tn();var nt=["gemini","chatgpt"];function en(){try{if(ot(Y)){let t=ve(Y,"utf8"),e=JSON.parse(t);if(typeof e.synthesizer==="string"){let r=e.synthesizer.toLowerCase();if(nt.includes(r))return r;process.stderr.write(`[greedysearch] Warning: unknown synthesizer "${e.synthesizer}" in ${Y}
334
- [greedysearch] Available synthesizers: ${nt.join(", ")}
335
- [greedysearch] Falling back to default: ${Rt}
336
- `)}}}catch{}return Rt}var Wt={perplexity:"perplexity.mjs",p:"perplexity.mjs",bing:"bing-copilot.mjs",b:"bing-copilot.mjs",google:"google-ai.mjs",g:"google-ai.mjs",gemini:"gemini.mjs",gem:"gemini.mjs",chatgpt:"chatgpt.mjs",gpt:"chatgpt.mjs","semantic-scholar":"semantic-scholar.mjs",semanticscholar:"semantic-scholar.mjs",s2:"semantic-scholar.mjs",logically:"logically.mjs",log:"logically.mjs"},De=qr(),Jt=De,Fl=en(),Yl=Math.max(1,Number.parseInt(process.env.GREEDY_FETCH_CONCURRENCY||"5",10)||5);process.env.CDP_PROFILE_DIR=ht;function rn(t){let e="",r=!1,n=!1;for(let a of String(t)){if(n){e+=a,n=!1;continue}if(a==="\\"){e+=a,n=!0;continue}if(a==='"'){r=!r,e+=a;continue}if(r&&a===`
337
- `)e+="\\n";else if(r&&a==="\r")e+="\\r";else if(r&&a==="\t")e+="\\t";else e+=a}return e}function wt(t){if(!t)return null;let e=String(t).trim(),r=e.indexOf("BEGIN_JSON"),n=e.indexOf("END_JSON");if(r!==-1&&n!==-1&&r<n)e=e.slice(r+10,n).trim();else{let f=e.indexOf("{");if(f>0)e=e.slice(f)}let a=[e,e.replace(/^```json\s*/i,"").replace(/^```\s*/i,"").replace(/```$/i,"").trim()],l=e.indexOf("{"),i=e.lastIndexOf("}");if(l!==-1&&i!==-1&&l<i)a.push(e.slice(l,i+1));for(let f of[...a]){let o=rn(f);if(o!==f)a.push(o)}for(let f of a)try{return JSON.parse(f)}catch{}return null}import{spawn as gn}from"node:child_process";import{basename as nn}from"node:path";function $t(t=process.env,e=process.execPath){let r=t.GREEDY_SEARCH_NODE||t.NODE_BINARY||t.NODE;if(r?.trim())return r.trim();let n=nn(e||"").toLowerCase();if(n==="node"||n==="node.exe")return e;return"node"}import{existsSync as Ee}from"node:fs";import{dirname as an,join as ct}from"node:path";import{fileURLToPath as ln}from"node:url";function Ce(t){return ln(new URL(".",t)).replace(/^\/([A-Z]:)/,"$1")}function fn(t,e=Ee){let r=new Set;for(let n of t.filter(Boolean)){if(r.has(n))continue;if(r.add(n),e(n))return n}return t.filter(Boolean).at(-1)}function Ne(t,{moduleDir:e,entrypoint:r=process.argv[1],env:n=process.env,exists:a=Ee}={}){let l=r?an(r):null,i=n.GREEDY_SEARCH_EXTENSION_DIR?.trim()||null,f=[e?ct(e,"..","..","extractors",t):null,e?ct(e,"..","extractors",t):null,i?ct(i,"extractors",t):null,l?ct(l,"..","extractors",t):null];return fn(f,a)}var on=Ce(import.meta.url),pn={gemini:"gemini.mjs",chatgpt:"chatgpt.mjs"};function hn(t="gemini"){let e=String(t||"gemini").toLowerCase();if(e==="gem")return"gemini";if(e==="gpt")return"chatgpt";return e}async function wn(t,e,{tabPrefix:r=null,timeoutMs:n=180000,visible:a=null}={}){let l=hn(t),i=pn[l];if(!i||!nt.includes(l))throw Error(`Unsupported synthesizer "${t}". Supported: ${nt.join(", ")}`);let f=Ne(i,{moduleDir:on});return new Promise((o,g)=>{let p=r?["--tab",String(r)]:[],h={...process.env,CDP_PROFILE_DIR:ht};if(a!==!0)delete h.GREEDY_SEARCH_VISIBLE,delete h.GREEDY_SEARCH_ALWAYS_VISIBLE;else h.GREEDY_SEARCH_VISIBLE="1",h.GREEDY_SEARCH_ALWAYS_VISIBLE="1";let m=gn($t(),[f,"--stdin",...p],{stdio:["pipe","pipe","pipe"],env:h});m.stdin.write(e),m.stdin.end();let c="",y="";m.stdout.on("data",(w)=>c+=w),m.stderr.on("data",(w)=>y+=w);let b=setTimeout(()=>{m.kill(),g(Error(`${l} prompt timed out after ${n/1000}s`))},n);m.on("close",(w)=>{if(clearTimeout(b),w!==0){g(Error(y.trim()||`${l} extractor failed`));return}try{o(JSON.parse(c.trim()))}catch{g(Error(`bad JSON from ${l}: ${c.slice(0,100)}`))}})})}async function x(t,e={}){return wn("gemini",t,e)}var Ga=Ya(new URL(".",import.meta.url)).replace(/^\/([A-Z]:)/,"$1"),Va=E(Ga,"..","..","bin","search.mjs"),Za=E(process.cwd(),".dm","greedysearch-research");function Ba(t){return String(t||"research").toLowerCase().replaceAll(/[^a-z0-9]+/g,"-").replaceAll(/^-|-$/g,"").slice(0,60)||"research"}function B(t,e=1/0){let r=new Set,n=[];for(let a of t||[]){let l=T(String(a||""),1000);if(!l||r.has(l))continue;if(r.add(l),n.push(l),n.length>=e)break}return n}async function Ka(...t){let{fetchMultipleSources:e}=await Promise.resolve().then(() => (ir(),lr));return e(...t)}async function le(...t){let{writeSourcesToFiles:e}=await Promise.resolve().then(() => (or(),gr));return e(...t)}function Ua({breadth:t=3,iterations:e=2,maxSources:r}){let n=ee(t,1,5,3),a=ee(e,1,3,2),l=ee(r??Math.max(5,n*a*2),3,12,8);return{breadth:n,iterations:a,maxSources:l}}function ee(t,e,r,n){let a=Number.parseInt(String(t??""),10);if(!Number.isFinite(a))return n;return Math.min(r,Math.max(e,a))}function Ia(t,e,r,{expand:n=!0,includeOriginal:a=!0,exclude:l=[]}={}){let i=Array.isArray(t?.queries)?t.queries:[],f=[],o=new Set([...l].map((g)=>A(g).toLowerCase()));for(let g of i){let p=typeof g==="string"?g:g?.query,h=typeof g==="string"?"":g?.researchGoal||"";re(f,p,h,{exclude:o})}if(a)re(f,e,"Original user query",{prepend:!0,exclude:o});if(n){let g=[{query:`${e} official docs GitHub`,researchGoal:"Find primary project docs, repository details, and maintainer claims."},{query:`${e} benchmarks limitations compatibility`,researchGoal:"Validate performance claims and uncover unsupported APIs or caveats."},{query:`${e} alternatives comparison production use cases`,researchGoal:"Compare against conventional headless browsers and identify when to choose it."},{query:`${e} anti bot detection Cloudflare screenshots visual rendering`,researchGoal:"Check automation risks, rendering gaps, screenshots, and bot-detection behavior."}];for(let p of g){if(f.length>=r)break;re(f,p.query,p.researchGoal,{exclude:o})}}return f.slice(0,r)}function re(t,e,r="",{prepend:n=!1,exclude:a=new Set}={}){if(!e||typeof e!=="string")return;let l=A(e);if(!l||a.has(l.toLowerCase())||t.some((f)=>f.query.toLowerCase()===l.toLowerCase()))return;let i={query:l,researchGoal:T(r,320)};if(n)t.unshift(i);else t.push(i)}function A(t){return xa(Xa(String(t)))}function Xa(t){let e="",r=0;while(r<t.length){let n=t.indexOf("[",r);if(n===-1){e+=t.slice(r);break}let a=t.indexOf("]",n+1);if(a===-1||t[a+1]!=="("||a===n+1){e+=t.slice(r,n+1),r=n+1;continue}let l=t.indexOf(")",a+2);if(l===-1){e+=t.slice(r,n+1),r=n+1;continue}let i=t.slice(a+2,l).trimStart();if(!i.startsWith("http://")&&!i.startsWith("https://")){e+=t.slice(r,n+1),r=n+1;continue}e+=t.slice(r,n),e+=t.slice(n+1,a),r=l+1}return e}function xa(t){let e="",r=!1;for(let n of t)if(n===" "||n==="\t"||n===`
338
- `||n==="\r"){if(!r)e+=" ";r=!0}else e+=n,r=!1;return e.trim()}function Er(t){return new Set(String(t).toLowerCase().normalize("NFD").replaceAll(/[\u0300-\u036f]/g,"").split(/[^\w]+/).filter((e)=>e.length>1))}function Et(t,e){let r=Er(t),n=Er(e),a=new Set([...r,...n]).size;if(a===0)return 1;let l=0;for(let i of r)if(n.has(i))l++;return l/a}function Or(t,e,{threshold:r=0.75,roundIndex:n=0,originalQuery:a=null}={}){let l=A(t).toLowerCase();if(e.has(l))return!0;if(a&&n>0&&l===A(a).toLowerCase())return!0;for(let i of e)if(Et(l,i)>=r)return!0;return!1}function Qa(t,e,r,n){let a=e.map((l)=>({queries:l.queries?.map((i)=>i.query||"")||[],learnings:l.learnings||[],gaps:l.gaps||[]}));return["You are evaluating the quality of an iterative research run.","Assess coverage across: official sources, limitations/risks, benchmarks/performance, production usage, and counter-evidence.","Score each dimension 0-10. Overall score 0-10.","Identify remaining knowledge gaps.","Propose targeted next actions (search queries or direct URL fetches) that would most improve the research.","Decide whether to continue or stop.","terminationReason must be one of: quality_threshold | max_rounds | no_novel_actions | insufficient_evidence.","",`Original research question: ${t}`,`Rounds completed: ${JSON.stringify(a,null,2)}`,`Accumulated learnings: ${JSON.stringify(r.slice(0,12),null,2)}`,`Known gaps: ${JSON.stringify(n.slice(0,8),null,2)}`,"","Respond ONLY with JSON wrapped in BEGIN_JSON / END_JSON markers:","BEGIN_JSON",JSON.stringify({score:7.5,coverage:{officialSources:8,limitations:5,benchmarks:7,productionUseCases:6,counterEvidence:4},knowledgeGaps:["specific gap or missing evidence"],shouldContinue:!0,terminationReason:"quality_threshold",nextActions:[{type:"search",query:"targeted search query"},{type:"fetchUrl",url:"https://example.com/primary-doc"}]},null,2),"END_JSON"].join(`
339
- `)}function za(t,e,r,n,a){let l=[],i=[{template:(f)=>`${f} official documentation`,label:"official docs"},{template:(f)=>`${f} GitHub issues discussions`,label:"community signals"},{template:(f)=>`${f} benchmarks performance comparison`,label:"benchmarks"},{template:(f)=>`${f} limitations risks caveats`,label:"limitations"},{template:(f)=>`${f} production deployment experience`,label:"production usage"},{template:(f)=>`${e} ${f} counter evidence`,label:"counter-evidence"}];for(let f=0;f<t.length&&l.length<n;f++){let o=t[f],g=i[f%i.length],p=g.template(o);if(!Or(p,r,{roundIndex:a}))l.push({query:p,researchGoal:`Gap-driven: ${o} (${g.label})`})}return l}async function Sa(t,e,r,n,a){try{let l=await x(Qa(t,e,r,n),{timeoutMs:120000}),i=lt(l,{}),f=typeof i.score==="number"?Math.min(10,Math.max(0,i.score)):a.length>0?a[a.length-1]:5,o=Array.isArray(i.knowledgeGaps)?i.knowledgeGaps.map((m)=>String(m)).filter(Boolean).slice(0,6):[],g=Array.isArray(i.nextActions)?i.nextActions.slice(0,5):[],p=typeof i.shouldContinue==="boolean"?i.shouldContinue:f<8,h=i.terminationReason||null;return{score:f,coverage:i.coverage||{},knowledgeGaps:o,shouldContinue:p,nextActions:g,terminationReason:h||(f>=8.5?"quality_threshold":null),evaluationError:""}}catch(l){return process.stderr.write(`[greedysearch] Quality evaluation failed: ${l.message}
340
- `),{score:a.length>0?a[a.length-1]:5,coverage:{},knowledgeGaps:[],shouldContinue:!0,nextActions:[],terminationReason:null,evaluationError:l.message}}}function ua(t){let e={};for(let r of Object.keys(t||{}).filter((n)=>!n.startsWith("_"))){let n=t?.[r];if(!n)continue;e[r]=n.error?{status:"error",error:String(n.error)}:{status:"ok",answer:T(n.answer||"",1400),sources:Array.isArray(n.sources)?n.sources.slice(0,5).map((a)=>({title:T(a.title||"",160),url:a.url||""})):[]}}return e}function qa(t,e,r=[],n=[],a=[]){let l=n.length>0?`
398
+ ${$}`,tree:w}}return{ok:!1,error:"Unsupported GitHub URL type"}}catch(l){return{ok:!1,error:l.message}}}var Xf;var Uf=qt(()=>{Xf={"user-agent":"GreedySearch/1.0",accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});import{spawn as Ca}from"node:child_process";import{basename as lp}from"node:path";function jt(t=process.env,n=process.execPath){let f=t.GREEDY_SEARCH_NODE||t.NODE_BINARY||t.NODE;if(f?.trim())return f.trim();let p=lp(n||"").toLowerCase();if(p==="node"||p==="node.exe")return n;return"node"}import{mkdirSync as Mn,writeFileSync as J}from"node:fs";import{join as Y}from"node:path";import{fileURLToPath as va}from"node:url";var wp=["fbclid","gclid","ref","ref_src","ref_url","source","utm_campaign","utm_content","utm_medium","utm_source","utm_term"],$p=["dev.to","hashnode.com","medium.com","reddit.com","stackoverflow.com","stackexchange.com","substack.com"],_p=["arstechnica.com","techcrunch.com","theverge.com","venturebeat.com","wired.com","zdnet.com"],dn=["facebook.com","instagram.com","linkedin.com","pinterest.com","tiktok.com","twitter.com","x.com"];function H(t="",n=240){let f=String(t).replaceAll(/\s+/g," ").trim();if(f.length<=n)return f;let p=f.slice(0,n),g=p.lastIndexOf(" ");return g>0?`${p.slice(0,g)}...`:`${p}...`}function st(t=""){let n=H(t,180);if(!n)return"";if(/^https?:\/\//i.test(n))return"";let f=n.split(/\s+/).filter(Boolean).length,p=/[A-Z]/.test(n),g=/\d/.test(n);return n===n.toLowerCase()&&f<=4&&!p&&!g?"":n}function ut(t="",n=""){let f=st(t),p=st(n);if(!p)return f;if(!f)return p;let g=/^https?:\/\//i.test(f),r=/^https?:\/\//i.test(p);if(g&&!r)return p;if(!g&&r)return f;return p.length>f.length?p:f}function V(t){if(!t)return null;try{let n=new URL(t);if(!["http:","https:"].includes(n.protocol))return null;if(n.hash="",n.hostname=n.hostname.toLowerCase(),n.protocol==="https:"&&n.port==="443"||n.protocol==="http:"&&n.port==="80")n.port="";for(let g of[...n.searchParams.keys()]){let r=g.toLowerCase();if(wp.includes(r)||r.startsWith("utm_"))n.searchParams.delete(g)}n.searchParams.sort();let f=n.pathname.replace(/\/{1,10}$/,"")||"/";n.pathname=f;let p=n.toString();return f==="/"?p.replace(/\/$/,""):p}catch{return null}}function hp(t){try{return new URL(t).hostname.toLowerCase().replace(/^www\./,"")}catch{return""}}function it(t,n){return n.some((f)=>t===f||t.endsWith(`.${f}`))}function tn(t,n="",f=""){let p=n.toLowerCase(),g=f.toLowerCase();if(t==="github.com"||t==="gitlab.com")return"repo";if(t==="arxiv.org"||t==="doi.org"||t==="semanticscholar.org"||t.endsWith(".semanticscholar.org")||g.includes("/paper/")||g.includes("/pdf/"))return"academic";if(it(t,dn))return"social";if(it(t,$p))return"community";if(it(t,_p))return"news";if(t.startsWith("docs.")||t.startsWith("developer.")||t.startsWith("developers.")||t.startsWith("api.")||p.includes("documentation")||p.includes("docs")||p.includes("reference")||g.includes("/docs/")||g.includes("/reference/")||g.includes("/api/"))return"official-docs";if(t.startsWith("blog.")||g.includes("/blog/"))return"maintainer-blog";return"website"}function ep(t){switch(t){case"official-docs":return 5;case"repo":return 4;case"academic":return 4;case"maintainer-blog":return 3;case"website":return 2;case"community":return 1;case"news":return 0;case"social":return-6;default:return 0}}function Ep(t){let n=Object.values(t.perEngine||{}).map((f)=>f?.rank||99);return n.length?Math.min(...n):99}var Dp=["reddit.com","news.ycombinator.com","lobste.rs"];function ht(t){return t.smartScore*3+t.engineCount*5+ep(t.sourceType)*2+Math.max(0,7-Ep(t))}function bp(t){let n=t.toLowerCase(),f=[];if(n.includes("openai")||n.includes("gpt")||n.includes("chatgpt"))f.push("openai.com","platform.openai.com","help.openai.com");if(n.includes("anthropic")||n.includes("claude"))f.push("anthropic.com","docs.anthropic.com");if(n.includes("bun"))f.push("bun.sh","bun.com");if(n.includes("next.js")||n.includes("nextjs"))f.push("nextjs.org","vercel.com");if(n.includes("playwright"))f.push("playwright.dev");if(n.includes("supabase"))f.push("supabase.com","supabase.io");if(n.includes("prisma"))f.push("prisma.io");if(n.includes("tailwind"))f.push("tailwindcss.com");if(n.includes("vite"))f.push("vitejs.dev","vite.dev");if(n.includes("astro"))f.push("astro.build");if(n.includes("svelte"))f.push("svelte.dev");if(n.includes("solid"))f.push("solidjs.com");if(n.includes("vue")||n.includes("nuxt"))f.push("vuejs.org","nuxt.com");if(n.includes("react")||n.includes("react native"))f.push("react.dev","reactnative.dev");if(n.includes("angular"))f.push("angular.io","angular.dev");if(n.includes("node.js")||n.includes("nodejs"))f.push("nodejs.org","nodejs.dev","npmjs.com");if(/\bgo\b/.test(n)||n.includes("golang"))f.push("go.dev","golang.org","pkg.go.dev");if(n.includes("deno"))f.push("deno.land","deno.com");if(n.includes("fresh"))f.push("fresh.deno.dev");if(n.includes("typescript")||n.includes("ts"))f.push("typescriptlang.org");if(n.includes("python"))f.push("python.org","docs.python.org");if(n.includes("rust"))f.push("rust-lang.org","docs.rs","crates.io");if(n.includes("zig"))f.push("ziglang.org");if(n.includes("docker"))f.push("docker.com","docs.docker.com","hub.docker.com");if(n.includes("kubernetes")||n.includes("k8s"))f.push("kubernetes.io","k8s.io");if(n.includes("postgres")||n.includes("postgresql"))f.push("postgresql.org","neon.tech","supabase.com");if(n.includes("redis"))f.push("redis.io");if(n.includes("sqlite"))f.push("sqlite.org");if(n.includes("cloudflare"))f.push("developers.cloudflare.com","cloudflare.com");if(n.includes("vercel"))f.push("vercel.com","nextjs.org");if(n.includes("netlify"))f.push("netlify.com","docs.netlify.com");if(n.includes("stripe"))f.push("stripe.com","docs.stripe.com");if(n.includes("github"))f.push("github.com","docs.github.com");if(n.includes("gitlab"))f.push("gitlab.com","docs.gitlab.com");if(n.includes("aws"))f.push("aws.amazon.com","docs.aws.amazon.com");if(n.includes("azure"))f.push("azure.microsoft.com","learn.microsoft.com");if(n.includes("gcp")||n.includes("google cloud"))f.push("cloud.google.com","developers.google.com");if(n.includes("gemini")||n.includes("google ai"))f.push("ai.google.dev","developers.google.com");for(let p of dn){let g=p.replace(/\.com$/,"");if(n.includes(g))f.push(p)}return[...new Set(f)]}function cn(t,n){return t===n||t.endsWith(`.${n}`)}function At(t,n=""){let f=new Map,p=Object.keys(t||{}).filter(($)=>!$.startsWith("_")),g=bp(n);for(let $ of p){let _=t[$];if(!_?.sources)continue;for(let e=0;e<_.sources.length;e++){let E=_.sources[e],h=V(E.url);if(!h||h.length<10)continue;let b=st(E.title||""),D=hp(h),v=tn(D,b,h),P=0;if(g.some((I)=>cn(D,I)))P+=10;if(v==="official-docs")P+=3;let R=h.toLowerCase();if(/\/docs\/|\/documentation\/|\.dev\/|\/api\/|\/reference\//.test(R))P+=2;let y=g.some((I)=>cn(D,I));if(v==="social"&&!y)P-=20;if(g.length>0){if(it(D,Dp))P-=3;else if(v==="community"&&!it(D,["stackoverflow.com","stackexchange.com"]))P-=1}let j=f.get(h)||{id:"",canonicalUrl:h,displayUrl:E.url||h,domain:D,title:"",engines:[],engineCount:0,perEngine:{},sourceType:v,isOfficial:v==="official-docs",smartScore:0};if(j.title=ut(j.title,b),j.displayUrl=j.displayUrl||E.url||h,j.sourceType=j.sourceType||v,j.isOfficial=j.isOfficial||v==="official-docs",j.smartScore=Math.max(j.smartScore,P),!j.engines.includes($))j.engines.push($);j.perEngine[$]={rank:e+1,title:ut(j.perEngine[$]?.title||"",b)},f.set(h,j)}}let r=Array.from(f.values()).map(($)=>({...$,engineCount:$.engines.length})),a=r.filter(($)=>$.sourceType!=="social"),l=r.filter(($)=>$.sourceType==="social");return a.sort(($,_)=>{let e=ht(_)-ht($);if(e!==0)return e;return $.domain.localeCompare(_.domain)}),l.sort(($,_)=>{let e=ht(_)-ht($);if(e!==0)return e;return $.domain.localeCompare(_.domain)}),[...a,...l].slice(0,12).map(($,_)=>({...$,id:`S${_+1}`,title:$.title||$.domain||$.canonicalUrl}))}function Ft(t,n){let f=new Map(n.map((p)=>[p.id,p]));return t.map((p)=>{let g=f.get(p.id);if(!g)return p;let r=ut(p.title,g.title||"");return{...p,title:r||p.title,fetch:{attempted:!0,ok:!g.error&&g.contentChars>100,status:g.status||null,finalUrl:g.finalUrl||g.url||p.canonicalUrl,contentType:g.contentType||"",lastModified:g.lastModified||"",publishedTime:g.publishedTime||"",byline:g.byline||"",siteName:g.siteName||"",lang:g.lang||"",title:g.title||"",snippet:g.snippet||"",contentChars:g.contentChars||0,source:g.source||"unknown",duration:g.duration||0,error:g.error||""}}})}import{existsSync as Gt,mkdirSync as Cp,readFileSync as qn,writeFileSync as vp}from"node:fs";import{homedir as jp}from"node:os";import{join as sn}from"node:path";import{tmpdir as Pp}from"node:os";function Rp(t,n=9222){let f=Number.parseInt(String(t??""),10);return Number.isInteger(f)&&f>1024&&f<65535?f:n}var yp=Pp().replaceAll("\\","/"),hr=Rp(process.env.GREEDY_SEARCH_PORT),K=(process.env.GREEDY_SEARCH_PROFILE_DIR||process.env.CDP_PROFILE_DIR||`${yp}/greedysearch-chrome-profile`).replaceAll("\\","/"),er=`${K}/DevToolsActivePort`,Er=process.env.GREEDY_SEARCH_PID_FILE||`${K}/browser.pid`,Dr=process.env.CDP_PAGES_CACHE||`${K}/cdp-pages.json`,br=process.env.GREEDY_SEARCH_MODE_FILE||`${K}/browser-mode`,Cr=process.env.GREEDY_SEARCH_METADATA_FILE||`${K}/browser-metadata.json`,vr=process.env.GREEDY_SEARCH_LAUNCH_LOCK_FILE||`${K}/browser-launch.lock`,jr=process.env.GREEDY_SEARCH_ACTIVITY_FILE||`${K}/browser-last-activity`,Pr=(process.env.CDP_SOCKET_DIR||`${K}/cdp-sockets`).replaceAll("\\","/"),Rr=`${K}/visible-recovery.jsonl`,fn=sn(jp(),".dm"),nt=sn(fn,"greedyconfig"),pn=["perplexity","google","chatgpt","gemini"],gn="gemini";function Op(){try{if(Gt(nt)){let t=qn(nt,"utf8"),n=JSON.parse(t);if(Array.isArray(n.engines)&&n.engines.length>0&&n.engines.every((f)=>typeof f==="string")){let f=n.engines.filter((g)=>nn[g]),p=n.engines.filter((g)=>!nn[g]);if(p.length>0)process.stderr.write(`[greedysearch] Warning: ignoring unknown engine(s) in ${nt}: ${p.join(", ")}
399
+ [greedysearch] Available engines: ${Object.keys(nn).join(", ")}
400
+ `);if(f.length>0)return f;process.stderr.write(`[greedysearch] Warning: no valid engines in ${nt}, falling back to defaults: ${pn.join(", ")}
401
+ `)}}}catch{}return pn}function Np(){try{if(!Gt(fn))Cp(fn,{recursive:!0});if(!Gt(nt))vp(nt,JSON.stringify({engines:pn,synthesizer:gn},null,2)+`
402
+ `,"utf8")}catch{}}Np();var Tt=["gemini","chatgpt"];function ip(){try{if(Gt(nt)){let t=qn(nt,"utf8"),n=JSON.parse(t);if(typeof n.synthesizer==="string"){let f=n.synthesizer.toLowerCase();if(Tt.includes(f))return f;process.stderr.write(`[greedysearch] Warning: unknown synthesizer "${n.synthesizer}" in ${nt}
403
+ [greedysearch] Available synthesizers: ${Tt.join(", ")}
404
+ [greedysearch] Falling back to default: ${gn}
405
+ `)}}}catch{}return gn}var nn={perplexity:"perplexity.mjs",p:"perplexity.mjs",bing:"bing-copilot.mjs",b:"bing-copilot.mjs",google:"google-ai.mjs",g:"google-ai.mjs",gemini:"gemini.mjs",gem:"gemini.mjs",chatgpt:"chatgpt.mjs",gpt:"chatgpt.mjs","semantic-scholar":"semantic-scholar.mjs",semanticscholar:"semantic-scholar.mjs",s2:"semantic-scholar.mjs",logically:"logically.mjs",log:"logically.mjs"},Pt=Op(),kt=Pt,yr=ip(),Or=Math.max(1,Number.parseInt(process.env.GREEDY_FETCH_CONCURRENCY||"5",10)||5);process.env.CDP_PROFILE_DIR=K;function Ap(t){let n="",f=!1,p=!1;for(let g of String(t)){if(p){n+=g,p=!1;continue}if(g==="\\"){n+=g,p=!0;continue}if(g==='"'){f=!f,n+=g;continue}if(f&&g===`
406
+ `)n+="\\n";else if(f&&g==="\r")n+="\\r";else if(f&&g==="\t")n+="\\t";else n+=g}return n}function ft(t){if(!t)return null;let n=String(t).trim(),f=n.indexOf("BEGIN_JSON"),p=n.indexOf("END_JSON");if(f!==-1&&p!==-1&&f<p)n=n.slice(f+10,p).trim();else{let l=n.indexOf("{");if(l>0)n=n.slice(l)}let g=[n,n.replace(/^```json\s*/i,"").replace(/^```\s*/i,"").replace(/```$/i,"").trim()],r=n.indexOf("{"),a=n.lastIndexOf("}");if(r!==-1&&a!==-1&&r<a)g.push(n.slice(r,a+1));for(let l of[...g]){let w=Ap(l);if(w!==l)g.push(w)}for(let l of g)try{return JSON.parse(l)}catch{}return null}import{spawn as Lp}from"node:child_process";import{existsSync as un}from"node:fs";import{dirname as Tp,join as Wt}from"node:path";import{fileURLToPath as kp}from"node:url";function tf(t){return kp(new URL(".",t)).replace(/^\/([A-Z]:)/,"$1")}function Hp(t,n=un){let f=new Set;for(let p of t.filter(Boolean)){if(f.has(p))continue;if(f.add(p),n(p))return p}return t.filter(Boolean).at(-1)}function nf(t,{moduleDir:n,entrypoint:f=process.argv[1],env:p=process.env,exists:g=un}={}){let r=f?Tp(f):null,a=p.GREEDY_SEARCH_EXTENSION_DIR?.trim()||null;return Hp([n?Wt(n,"..","..","extractors",t):null,n?Wt(n,"..","extractors",t):null,a?Wt(a,"extractors",t):null,r?Wt(r,"..","extractors",t):null],g)}var Yp=tf(import.meta.url),Ip={gemini:"gemini.mjs",chatgpt:"chatgpt.mjs"};function Mp(t="gemini"){let n=String(t||"gemini").toLowerCase();if(n==="gem")return"gemini";if(n==="gpt")return"chatgpt";return n}async function Fp(t,n,{tabPrefix:f=null,timeoutMs:p=180000,visible:g=null}={}){let r=Mp(t),a=Ip[r];if(!a||!Tt.includes(r))throw Error(`Unsupported synthesizer "${t}". Supported: ${Tt.join(", ")}`);return new Promise((l,w)=>{let $=nf(a,{moduleDir:Yp}),_=f?["--tab",String(f)]:[],e={...process.env,CDP_PROFILE_DIR:K};if(g!==!0)delete e.GREEDY_SEARCH_VISIBLE,delete e.GREEDY_SEARCH_ALWAYS_VISIBLE;else e.GREEDY_SEARCH_VISIBLE="1",e.GREEDY_SEARCH_ALWAYS_VISIBLE="1";let E=Lp(jt(),[$,"--stdin",..._],{stdio:["pipe","pipe","pipe"],env:e});E.stdin.write(n),E.stdin.end();let h="",b="";E.stdout.on("data",(v)=>h+=v),E.stderr.on("data",(v)=>b+=v);let D=setTimeout(()=>{E.kill(),w(Error(`${r} prompt timed out after ${p/1000}s`))},p);E.on("close",(v)=>{if(clearTimeout(D),v!==0){w(Error(b.trim()||`${r} extractor failed`));return}try{l(JSON.parse(h.trim()))}catch{w(Error(`bad JSON from ${r}: ${h.slice(0,100)}`))}})})}async function X(t,n={}){return Fp("gemini",t,n)}var Gp=30000;function ff(t,n,f,p){let g=Number.parseInt(String(t??""),10);if(!Number.isFinite(g))return p;return Math.min(f,Math.max(n,g))}async function pf(t){let n=["You are a research complexity classifier.","Classify the following query by research complexity.","","- simple: A narrow factual question (what is X, define X, how does X work)."," Answerable with 1-3 search queries and a short synthesis. No sub-questions.","- moderate: A focused comparison, recent change, or best-practice lookup."," Needs 2-4 angles but stays within one domain.","- complex: Multi-faceted survey, landscape analysis, or cross-domain investigation."," Benefits from parallel research directions and iterative deepening.","","Respond ONLY with JSON wrapped in BEGIN_JSON / END_JSON markers:","BEGIN_JSON",JSON.stringify({complexity:"simple",reasoning:"narrow factual question",suggestedBreadth:1,suggestedIterations:1,needsAcademicSources:!1},null,2),"END_JSON","","Query: "+t].join(`
407
+ `);try{let f=await X(n,{timeoutMs:Gp}),p=ft(f?.answer||"")||{},g=["simple","moderate","complex"].includes(p.complexity)?p.complexity:"moderate";return{complexity:g,reasoning:H(p.reasoning||"",200),suggestedBreadth:ff(p.suggestedBreadth,1,5,g==="simple"?1:3),suggestedIterations:ff(p.suggestedIterations,1,3,g==="simple"?1:2),needsAcademicSources:p.needsAcademicSources===!0}}catch(f){return process.stderr.write(`[greedysearch] Complexity classification failed, defaulting to moderate: ${f.message}
408
+ `),{complexity:"moderate",reasoning:"classification failed",suggestedBreadth:3,suggestedIterations:2,needsAcademicSources:!1}}}an();Xt();function sg(t){if(t<1000)return"0s";let n=Math.round(t/1000);if(n<60)return`${n}s`;let f=Math.floor(n/60),p=n%60;return`${f}m ${p}s`}function ug(t,n=20){let f=Math.round(t*n),p=n-f;return"["+"█".repeat(f)+"░".repeat(p)+"]"}function ot({totalActions:t=0,totalRounds:n=0,totalFetches:f=0,silent:p=!1}={}){let g=Date.now(),r=0,a=0,l=0,w=[],$=null,_=null,e=0,E=500;function h(P){if(w.push(P),w.length>5)w.shift()}function b(){if(w.length===0)return null;return w.reduce((P,R)=>P+R,0)/w.length}function D(P){let R=Date.now()-g,y=t+f+n,j=r+l+a,I=y>0?Math.min(1,j/y):0,M=ug(I),A=b(),k=Math.max(0,y-j),F=A?A*k:null,et=F?sg(F):"—",d=_?` ${_}`:"";return`${M} ${j}/${y} (${P}${d}, ETA ${et})`}function v(P){if(p)return;let R=Date.now();if(R-e<E&&P!=="done")return;e=R,process.stderr.write(`[greedysearch] ${D(P)}
409
+ `)}return{startRound(P){a=P-1},endRound(){a++,v("round")},startAction(P,R){$=Date.now(),_=`${P}:${(R||"").slice(0,40)}`,v(P)},endAction(){if($)h(Date.now()-$),$=null;r++,v("action")},startFetch(P){$=Date.now(),_=`fetch:${(P||"").slice(0,40)}`,v("fetch")},endFetch(P=!0){if($)h(Date.now()-$),$=null;l++,v(P?"fetch":"fetch-failed")},print(){v("progress")},finish(){v("done")},getElapsedMs(){return Date.now()-g}}}import{spawn as ta}from"node:child_process";import{join as na}from"node:path";import{fileURLToPath as fa}from"node:url";var pa=fa(new URL(".",import.meta.url)).replace(/^\/([A-Z]:)/,"$1"),ga=na(pa,"..","..","bin","search.mjs");function mf(t,n=1/0){let f=new Set,p=[];for(let g of t||[]){let r=H(String(g||""),1000);if(!r||f.has(r))continue;if(f.add(r),p.push(r),p.length>=n)break}return p}function aa(t){let n=String(t||"").trim();if(!n)return[];return[`${n} — definition and overview`,`${n} — how it works, mechanism, or key details`,`${n} — current usage, comparison, or best practices`]}function ra(t,n){let f=new Map;for(let p of t||[]){let g=p?.canonicalUrl||p?.finalUrl||p?.url;if(g)f.set(g,p)}for(let p of n||[]){let g=p?.canonicalUrl||p?.finalUrl||p?.url;if(!g)continue;if(f.has(g)){let r={...f.get(g),angles:[...f.get(g).angles||[f.get(g).query||""],p.query||""]};f.set(g,r)}else f.set(g,p)}return Array.from(f.values())}var la=Pt.join("|"),wa=new RegExp(`^\\[(${la})\\]`);function $a(t){return/^PROGRESS:/.test(t)||/^\[greedysearch\]/.test(t)||wa.test(t)||/^GreedySearch Chrome/.test(t)||/^Launching GreedySearch Chrome/.test(t)||/^Headless mode/.test(t)||/^Ready\.?$/.test(t)}async function _a(t,{locale:n=null,short:f=!0}={}){let p=[ga,"all","--inline","--stdin","--fast"];if(!f)p.push("--full");if(n)p.push("--locale",n);return new Promise((g,r)=>{let a=ta(jt(),p,{stdio:["pipe","pipe","pipe"],env:{...process.env,GREEDY_SEARCH_RESEARCH_CHILD:"1"}});a.stdin.write(t),a.stdin.end();let l="",w="",$="";a.stdout.on("data",(e)=>l+=e),a.stderr.on("data",(e)=>{w+=e,$+=e.toString();let E=$.split(`
410
+ `);$=E.pop()||"";for(let h of E)if($a(h))process.stderr.write(`${h}
411
+ `)});let _=setTimeout(()=>{a.kill(),r(Error(`research child search timed out for: ${t}`))},140000);a.on("close",(e)=>{if(clearTimeout(_),e!==0){r(Error(w.trim()||`search child exited with code ${e}`));return}try{g(JSON.parse(l.trim()))}catch{r(Error(`Invalid JSON from research child: ${l.slice(0,200)}`))}})})}function ha(t,n){let f=new Map;for(let p of n||[]){let g=V(p?.canonicalUrl||p?.finalUrl||p?.url);if(g&&p?.id)f.set(g,p.id)}return(t||[]).map((p,g)=>{let r=V(p?.finalUrl||p?.canonicalUrl||p?.url);return{...p,id:p?.id||f.get(r)||`F${g+1}`}})}function ea(t){let n=t.length,f=t.filter((p)=>p.status==="closed").length;return{total:n,closed:f,open:Math.max(0,n-f)}}async function Jf({query:t,locale:n=null,maxSources:f=5,qualityThreshold:p=8.5,writeBundle:g=process.env.GREEDY_RESEARCH_BUNDLE!=="0",researchOutDir:r=null}={}){let a=new Date().toISOString(),l=Date.now(),w=Ln(t),$=new Set;process.stderr.write(`[greedysearch] Simple research mode: single-pass for "${H(t,80)}"
412
+ `);let E=ot({totalActions:6,totalRounds:1,totalFetches:1,silent:process.env.GREEDY_RESEARCH_QUIET==="1"});E.startRound(1);let h=[],b=[],D=aa(t),v=[];E.startAction("search",`${D.length} angles in parallel`);let P=await Promise.allSettled(D.map((N)=>_a(N,{locale:n,short:!0})));for(let N=0;N<D.length;N++){let o=D[N],lt=P[N];if(E.endAction(),lt.status==="fulfilled"){let Z=lt.value;v.push({angle:o,result:Z});let T=At(Z,o);h=ra(h,T)}else process.stderr.write(`[greedysearch] Simple search angle "${o}" failed: ${lt.reason.message}
413
+ `)}if(process.stderr.write(`PROGRESS:research:simple:fetching
414
+ `),h.length>0)try{E.startFetch(`top ${Math.min(f,h.length)} sources`),b=await On(h,Math.min(f,h.length),8000,Math.min(3,f)),E.endFetch(!0),h=Ft(h,b)}catch(N){E.endFetch(!1),process.stderr.write(`[greedysearch] Source fetching failed: ${N.message}
415
+ `)}b=ha(b,h),process.stderr.write(`PROGRESS:research:simple:evidence
416
+ `);let R=[];try{let N=await Zf({query:t,questions:w,fetchedSources:b,extractedSourceKeys:$});R=N.evidence||[];for(let o of N.evidence){let lt=Array.isArray(o.answers)?o.answers:[];for(let T of lt){let $t=T?.id||T?.question;if($t){let q=w.find((xt)=>xt.id===$t);if(q){if(q.status="closed",q.closedRound=1,T.evidence)q.evidence=mf([...q.evidence||[],T.evidence],4)}}}let Z=Array.isArray(o.newQuestions)?o.newQuestions:[];for(let T of Z){let $t=H(String(T),320);if($t&&!w.some((q)=>q.question===$t))w.push({id:`Q${w.length+1}`,question:$t,status:"open",reason:"Discovered gap/follow-up",createdRound:1,evidence:[],sourceIds:[]})}}}catch(N){process.stderr.write(`[greedysearch] Evidence extraction failed: ${N.message}
417
+ `)}process.stderr.write(`PROGRESS:research:simple:synthesizing
418
+ `);let y={answer:"",agreement:{level:"mixed",summary:"Single-pass synthesis."},differences:[],caveats:[],claims:[],recommendedSources:h.slice(0,4).map((N)=>N.id),synthesized:!1};if(R.length>0)try{E.startAction("synth-evidence","from evidence");let N=await X(Tn(t,h,w,R),{timeoutMs:120000});E.endAction(),y={...y,...ft(N?.answer||"")||{}},y.synthesized=Array.isArray(y.claims)&&y.claims.length>0}catch(N){process.stderr.write(`[greedysearch] Evidence synthesis failed: ${N.message}
419
+ `)}if(!y.synthesized&&h.length>0)try{E.startAction("synth-final","fallback report");let N=await X(An(t,[{round:1,learnings:[],gaps:[],actions:[]}],h,w,R),{timeoutMs:120000});E.endAction(),y={...y,...ft(N?.answer||"")||{}},y.synthesized=Array.isArray(y.claims)&&y.claims.length>0}catch(N){process.stderr.write(`[greedysearch] Final synthesis failed: ${N.message}
420
+ `)}process.stderr.write(`PROGRESS:research:simple:audit
421
+ `);let j=kn(y.answer||"",h),I=await Hn(h,j);Yn(w,y,j);let M=mf(y.caveats||[]),A=Bt({sources:h,fetchedSources:b,synthesis:y,citationAudit:j,gaps:M,questions:w,rounds:[{round:1,actions:[],learnings:[],gaps:M}],qualityScore:y.synthesized?8:5,qualityThreshold:p,maxSources:f}),k=new Date().toISOString(),F=Date.now()-l,et={startedAt:a,finishedAt:k,durationMs:F,rounds:1,terminationReason:"simple_single_pass"},d=null,wt;if(g){process.stderr.write(`PROGRESS:research:simple:bundle
422
+ `);try{d=await In({query:t,rounds:[{round:1,actions:[],learnings:[],gaps:M,evidence:R}],sources:h,fetchedSources:b,evidenceItems:R,synthesis:y,citationAudit:j,citationUrls:I,floor:A,manifest:{...et,engines:kt,synthesizer:"gemini",actionsRun:1,searches:1,fetches:b.length,sourcesFetched:b.filter((N)=>N?.contentChars>100).length,engineFailures:[],floorMet:A.floorMet},allGaps:M,questions:w,outDir:r}),wt=d.sourceFiles,delete d.sourceFiles}catch(N){process.stderr.write(`[greedysearch] Research bundle write failed: ${N.message}
423
+ `),d={error:N.message||String(N)},wt=await Vt(b)}}else wt=await Vt(b);return process.stderr.write(`PROGRESS:research:done
424
+ `),E.endRound(),E.finish(),{query:t,_research:{mode:"simple",breadth:1,iterations:1,maxSources:f,rounds:[{round:1,actions:[],learnings:[],gaps:M,evidence:R}],learnings:[],gaps:M,evidence:R,questions:w,questionProgress:ea(w),qualityHistory:[y.synthesized?8:5],terminationReason:"simple_single_pass",qualityThreshold:p,floor:A,bundle:d,manifest:et},_citationAudit:j,_citationUrls:I,_sources:h,_fetchedSources:wt,_synthesis:y,_confidence:{sourcesCount:h.length,fetchedSourceSuccessRate:b.length>0?b.filter((N)=>N.contentChars>100).length/b.length:0,agreementLevel:y.agreement?.level||"mixed",floorMet:A.floorMet}}}var ja=va(new URL(".",import.meta.url)).replace(/^\/([A-Z]:)/,"$1"),Pa=Y(ja,"..","..","bin","search.mjs"),Ra=Y(process.cwd(),".pi","greedysearch-research"),ya=28000;function Oa(t){return String(t||"research").toLowerCase().replaceAll(/[^a-z0-9]+/g,"-").replaceAll(/^-|-$/g,"").slice(0,60)||"research"}function rt(t,n=1/0){let f=new Set,p=[];for(let g of t||[]){let r=H(String(g||""),1000);if(!r||f.has(r))continue;if(f.add(r),p.push(r),p.length>=n)break}return p}async function Na(...t){let{fetchMultipleSources:n}=await Promise.resolve().then(() => (Xt(),Nn));return n(...t)}async function mn(...t){let{writeSourcesToFiles:n}=await Promise.resolve().then(() => (an(),af));return n(...t)}function ia({breadth:t=3,iterations:n=2,maxSources:f}){let p=Fn(t,1,5,3),g=Fn(n,1,3,2),r=Fn(f??Math.max(5,p*g*2),3,12,8);return{breadth:p,iterations:g,maxSources:r}}function Fn(t,n,f,p){let g=Number.parseInt(String(t??""),10);if(!Number.isFinite(g))return p;return Math.min(f,Math.max(n,g))}function Aa(t,n,f,{expand:p=!0,includeOriginal:g=!0,exclude:r=[]}={}){let a=Array.isArray(t?.queries)?t.queries:[],l=[],w=new Set([...r].map(($)=>c($).toLowerCase()));for(let $ of a){let _=typeof $==="string"?$:$?.query,e=typeof $==="string"?"":$?.researchGoal||"";Gn(l,_,e,{exclude:w})}if(g)Gn(l,n,"Original user query",{prepend:!0,exclude:w});if(p){let $=[{query:`${n} official docs GitHub`,researchGoal:"Find primary project docs, repository details, and maintainer claims."},{query:`${n} benchmarks limitations compatibility`,researchGoal:"Validate performance claims and uncover unsupported APIs or caveats."},{query:`${n} alternatives comparison production use cases`,researchGoal:"Compare against conventional headless browsers and identify when to choose it."},{query:`${n} anti bot detection Cloudflare screenshots visual rendering`,researchGoal:"Check automation risks, rendering gaps, screenshots, and bot-detection behavior."}];for(let _ of $){if(l.length>=f)break;Gn(l,_.query,_.researchGoal,{exclude:w})}}return l.slice(0,f)}function Gn(t,n,f="",{prepend:p=!1,exclude:g=new Set}={}){if(!n||typeof n!=="string")return;let r=c(n);if(!r||g.has(r.toLowerCase())||t.some((l)=>l.query.toLowerCase()===r.toLowerCase()))return;let a={query:r,researchGoal:H(f,320)};if(p)t.unshift(a);else t.push(a)}function c(t){return ka(Ta(String(t)))}function Ta(t){let n="",f=0;while(f<t.length){let p=t.indexOf("[",f);if(p===-1){n+=t.slice(f);break}let g=t.indexOf("]",p+1);if(g===-1||t[g+1]!=="("||g===p+1){n+=t.slice(f,p+1),f=p+1;continue}let r=t.indexOf(")",g+2);if(r===-1){n+=t.slice(f,p+1),f=p+1;continue}let a=t.slice(g+2,r).trimStart();if(!a.startsWith("http://")&&!a.startsWith("https://")){n+=t.slice(f,p+1),f=p+1;continue}n+=t.slice(f,p),n+=t.slice(p+1,g),f=r+1}return n}function ka(t){let n="",f=!1;for(let p of t)if(p===" "||p==="\t"||p===`
425
+ `||p==="\r"){if(!f)n+=" ";f=!0}else n+=p,f=!1;return n.trim()}function Jn(t){return new Set(String(t).toLowerCase().normalize("NFD").replaceAll(/[\u0300-\u036f]/g,"").split(/[^\w]+/).filter((n)=>n.length>1))}function Kn(t,n){let f=Jn(t),p=Jn(n),g=new Set([...f,...p]).size;if(g===0)return 1;let r=0;for(let a of f)if(p.has(a))r++;return r/g}function zf(t,n,{threshold:f=0.75,roundIndex:p=0,originalQuery:g=null}={}){let r=c(t).toLowerCase();if(n.has(r))return!0;if(g&&p>0&&r===c(g).toLowerCase())return!0;for(let a of n)if(Kn(r,a)>=f)return!0;return!1}function Ha(t,n,f,p){let g=n.map((r)=>({queries:r.queries?.map((a)=>a.query||"")||[],learnings:r.learnings||[],gaps:r.gaps||[]}));return["You are evaluating the quality of an iterative research run.","Assess coverage across: official sources, limitations/risks, benchmarks/performance, production usage, and counter-evidence.","Score each dimension 0-10. Overall score 0-10.","Identify remaining knowledge gaps.","Propose targeted next actions (search queries or direct URL fetches) that would most improve the research.","Decide whether to continue or stop.","terminationReason must be one of: quality_threshold | max_rounds | no_novel_actions | insufficient_evidence.","",`Original research question: ${t}`,`Rounds completed: ${JSON.stringify(g,null,2)}`,`Accumulated learnings: ${JSON.stringify(f.slice(0,12),null,2)}`,`Known gaps: ${JSON.stringify(p.slice(0,8),null,2)}`,"","Respond ONLY with JSON wrapped in BEGIN_JSON / END_JSON markers:","BEGIN_JSON",JSON.stringify({score:7.5,coverage:{officialSources:8,limitations:5,benchmarks:7,productionUseCases:6,counterEvidence:4},knowledgeGaps:["specific gap or missing evidence"],shouldContinue:!0,terminationReason:"quality_threshold",nextActions:[{type:"search",query:"targeted search query"},{type:"fetchUrl",url:"https://example.com/primary-doc"}]},null,2),"END_JSON"].join(`
426
+ `)}function La(t,n,f,p,g){let r=[],a=[{template:(l)=>`${l} official documentation`,label:"official docs"},{template:(l)=>`${l} GitHub issues discussions`,label:"community signals"},{template:(l)=>`${l} benchmarks performance comparison`,label:"benchmarks"},{template:(l)=>`${l} limitations risks caveats`,label:"limitations"},{template:(l)=>`${l} production deployment experience`,label:"production usage"},{template:(l)=>`${n} ${l} counter evidence`,label:"counter-evidence"}];for(let l=0;l<t.length&&r.length<p;l++){let w=t[l],$=a[l%a.length],_=$.template(w);if(!zf(_,f,{roundIndex:g}))r.push({query:_,researchGoal:`Gap-driven: ${w} (${$.label})`})}return r}async function Ya(t,n,f,p,g){try{let r=await X(Ha(t,n,f,p),{timeoutMs:120000}),a=Ht(r,{}),l=typeof a.score==="number"?Math.min(10,Math.max(0,a.score)):g.length>0?g[g.length-1]:5,w=Array.isArray(a.knowledgeGaps)?a.knowledgeGaps.map((E)=>String(E)).filter(Boolean).slice(0,6):[],$=Array.isArray(a.nextActions)?a.nextActions.slice(0,5):[],_=typeof a.shouldContinue==="boolean"?a.shouldContinue:l<8,e=a.terminationReason||null;return{score:l,coverage:a.coverage||{},knowledgeGaps:w,shouldContinue:_,nextActions:$,terminationReason:e||(l>=8.5?"quality_threshold":null),evaluationError:""}}catch(r){return process.stderr.write(`[greedysearch] Quality evaluation failed: ${r.message}
427
+ `),{score:g.length>0?g[g.length-1]:5,coverage:{},knowledgeGaps:[],shouldContinue:!0,nextActions:[],terminationReason:null,evaluationError:r.message}}}function Ia(t){let n={};for(let f of Object.keys(t||{}).filter((p)=>!p.startsWith("_"))){let p=t?.[f];if(!p)continue;n[f]=p.error?{status:"error",error:String(p.error)}:{status:"ok",answer:H(p.answer||"",1400),sources:Array.isArray(p.sources)?p.sources.slice(0,5).map((g)=>({title:H(g.title||"",160),url:g.url||""})):[]}}return n}function Ma(t,n,f=[],p=[],g=[]){let r=p.length>0?`
341
428
  Known knowledge gaps to target:
342
- ${n.map((f)=>`- ${f}`).join(`
343
- `)}`:"",i=a.length>0?`
429
+ ${p.map((l)=>`- ${l}`).join(`
430
+ `)}`:"",a=g.length>0?`
344
431
  Already fetched URLs (do not re-fetch):
345
- ${a.map((f)=>`- ${f}`).join(`
346
- `)}`:"";return["You are planning web research actions for a multi-engine search agent.","You can plan two types of actions:",' - "search": run a multi-engine SERP search query',' - "fetchUrl": directly fetch a specific URL (docs page, GitHub repo, specification, etc.)','Prefer "fetchUrl" when a specific primary source URL is known or obvious.','Use "search" for broad discovery or when specific URLs are unknown.',`Return at most ${e} actions.`,"Avoid near-duplicate search queries and already-fetched URLs.","",`User topic: ${t}`,r.length?`
432
+ ${g.map((l)=>`- ${l}`).join(`
433
+ `)}`:"";return["You are planning web research actions for a multi-engine search agent.","You can plan two types of actions:",' - "search": run a multi-engine SERP search query',' - "fetchUrl": directly fetch a specific URL (docs page, GitHub repo, specification, etc.)','Prefer "fetchUrl" when a specific primary source URL is known or obvious.','Use "search" for broad discovery or when specific URLs are unknown.',`Return at most ${n} actions.`,"Avoid near-duplicate search queries and already-fetched URLs.","",`User topic: ${t}`,f.length?`
347
434
  Prior learnings to build on:
348
- ${r.map((f)=>`- ${f}`).join(`
349
- `)}`:"",l,i,"","Respond ONLY with JSON wrapped in BEGIN_JSON / END_JSON markers:","BEGIN_JSON",JSON.stringify({actions:[{type:"search",query:"specific search query",researchGoal:"what this action should clarify"},{type:"fetchUrl",url:"https://example.com/docs/relevant-page",researchGoal:"extract specific information from this page"}]},null,2),"END_JSON"].join(`
350
- `)}function Pr(t){if(!t||typeof t!=="object")return null;let e=t.type,r=T(t.researchGoal||"",320);if(e==="search"){if(t.query==null)return null;let n=A(t.query);return n?{type:"search",query:n,researchGoal:r}:null}if(e==="fetchUrl"){if(t.url==null)return null;let n=M(t.url);return n?{type:"fetchUrl",url:n,researchGoal:r}:null}return null}async function tl(t,{locale:e=null,short:r=!0,usedQueries:n,usedUrls:a,maxChars:l=8000}={}){if(t.type==="search"){let i=A(t.query).toLowerCase();n.add(i);try{let f=await $l(t.query,{locale:e,short:r}),o=Lt(f,t.query);return{ok:!0,action:t,result:f,sources:o}}catch(f){return{ok:!1,action:t,error:f.message,sources:[]}}}if(t.type==="fetchUrl"){let i=M(t.url);if(a.has(i))return{ok:!1,action:t,error:`URL already fetched: ${i}`,sources:[]};try{let f=await el(i,l);a.add(i);let o=nl(i),g={id:"",canonicalUrl:f.finalUrl||i,displayUrl:f.url||i,domain:o,title:f.title||i,engines:["fetch"],engineCount:1,perEngine:{},sourceType:Pt(o,f.title||"",f.finalUrl||i),isOfficial:!1,smartScore:0,fetch:{attempted:!0,ok:!f.error&&(f.contentChars||0)>100,status:f.status||null,finalUrl:f.finalUrl||i,content:f.content||"",contentChars:f.contentChars||0,snippet:f.snippet||"",error:f.error||""}};return{ok:!0,action:t,result:null,sources:[g],fetchResult:{id:g.id,url:i,finalUrl:f.finalUrl||i,title:f.title||"",content:f.content||"",contentChars:f.contentChars||0,snippet:f.snippet||"",status:f.status||null,error:f.error||"",source:f.source||"http",duration:f.duration||0}}}catch(f){return{ok:!1,action:t,error:f.message,sources:[]}}}return{ok:!1,action:t,error:`Unknown action type: ${t.type}`,sources:[]}}async function el(t,e){return await rl(t,e)}async function rl(t,e=8000){let r=Date.now();try{let{parseGitHubUrl:n,fetchGitHubContent:a}=await Promise.resolve().then(() => (ut(),St)),l=n(t);if(l&&(l.type==="root"||l.type==="tree"||l.type==="blob"&&!l.path?.includes("."))){let i=await a(t);if(i.ok){let{trimContentHeadTail:f}=await Promise.resolve().then(() => qt),o=f(i.content,e);return{url:t,finalUrl:t,status:200,title:i.title,snippet:o.slice(0,320),content:o,contentChars:o.length,source:"github-api",duration:Date.now()-r}}}}catch{}try{let{fetchSourceHttp:n}=await Promise.resolve().then(() => (Dr(),jr)),{trimContentHeadTail:a}=await Promise.resolve().then(() => qt),l=await n(t,{timeoutMs:1e4});if(l.ok){let i=a(l.markdown,e);return{url:t,finalUrl:l.finalUrl,status:l.status,title:l.title,snippet:l.excerpt,content:i,contentChars:i.length,source:"http",duration:Date.now()-r}}}catch{}return{url:t,title:"",content:"",contentChars:0,snippet:"",error:"HTTP fetch failed",source:"error",duration:Date.now()-r}}function nl(t){try{return new URL(t).hostname.toLowerCase().replace(/^www\./,"")}catch{return""}}async function al(t,e){let r=[],{parseGitHubUrl:n}=await Promise.resolve().then(() => (ut(),St));for(let a of t){if(a.type!=="fetchUrl"){r.push(a);continue}let l=n(a.url);if(!l||l.type!=="root"){r.push(a);continue}let{owner:i,repo:f}=l,o=`https://github.com/${i}/${f}`;if(e.has(o))continue;let g=[o],p=[`${o}/blob/main/CONTRIBUTING.md`,`${o}/blob/master/CONTRIBUTING.md`,`${o}/blob/main/CHANGELOG.md`,`${o}/blob/master/CHANGELOG.md`,`${o}/blob/main/docs/README.md`];for(let h of p){if(g.length>=3)break;if(!e.has(h))g.push(h)}for(let h of g)r.push({type:"fetchUrl",url:h,researchGoal:a.researchGoal||`Fetch GitHub content for ${i}/${f}`})}return r}function ll(t,e){let r=wt(t?.answer||"")||{},n=Array.isArray(r?.actions)?r.actions:[],a=[];for(let l of n){let i=Pr(l);if(i&&a.length<e)a.push(i)}return a}function il(t){return(t||[]).map((e)=>({type:"search",query:typeof e==="string"?e:e.query,researchGoal:typeof e==="string"?"":e.researchGoal||""})).filter((e)=>e.query)}function Dt(t){return M(t?.finalUrl||t?.canonicalUrl||t?.url||"")||t?.id||""}function fl(t,e,r,n=new Set){let a=(e||[]).filter((i)=>i.status!=="closed").slice(0,12).map((i)=>({id:i.id,question:i.question})),l=(r||[]).filter((i)=>i?.content||i?.snippet).filter((i)=>!n.has(Dt(i))).slice(0,6).map((i,f)=>({id:i.id||`F${f+1}`,title:i.title||"",url:i.finalUrl||i.url||i.canonicalUrl||"",content:T(i.content||i.snippet||"",5000)}));return["You are doing goal-based evidence extraction for an iterative research run.","For each source, extract only information that helps answer the open questions.","Use original wording/details where useful. Do not invent answers; leave questions open if evidence is insufficient.","If a source answers one or more tracked questions, identify those question IDs explicitly.","Also propose genuinely new sub-questions discovered from the evidence.","",`Original research question: ${t}`,`Open question ledger: ${JSON.stringify(a,null,2)}`,`Fetched sources: ${JSON.stringify(l,null,2)}`,"","Respond ONLY with JSON wrapped in BEGIN_JSON / END_JSON markers:","BEGIN_JSON",JSON.stringify({extractions:[{sourceId:"S1",url:"https://example.com/source",rational:"why this source matters for the goal",evidence:"specific quoted/paraphrased evidence with numbers, dates, caveats",summary:"concise contribution to the research question",answers:[{id:"Q1",evidence:"brief evidence that closes the question"}],newQuestions:["new sub-question raised by this source"]}]},null,2),"END_JSON"].join(`
351
- `)}function gl(t,e){let r=Array.isArray(t?.extractions)?t.extractions:[],n=new Map,a=new Map;for(let l of e||[]){if(l?.id)a.set(String(l.id),l);let i=Dt(l);if(i)n.set(i,l)}return r.map((l)=>{let i=a.get(String(l?.sourceId||""))||n.get(M(l?.url||"")||""),f=String(l?.sourceId||i?.id||""),o=M(l?.url||i?.finalUrl||i?.url||""),g=Array.isArray(l?.answers)?l.answers.map((p)=>({id:String(p?.id||""),evidence:T(p?.evidence||"",500),sourceIds:[f].filter(Boolean)})).filter((p)=>p.id):[];return{sourceId:f,url:o,title:i?.title||l?.title||"",rational:T(l?.rational||"",700),evidence:T(l?.evidence||"",1600),summary:T(l?.summary||"",700),answers:g,newQuestions:B(l?.newQuestions||[],6)}}).filter((l)=>l.sourceId||l.url||l.summary||l.evidence)}async function ol({query:t,questions:e,fetchedSources:r,extractedSourceKeys:n}){let a=(r||[]).filter((l)=>(l?.content||l?.snippet)&&!n.has(Dt(l)));if(a.length===0)return{evidence:[],error:""};try{let l=await x(fl(t,e,a,n),{timeoutMs:120000}),i=lt(l,{extractions:[]}),f=gl(i,a);for(let o of a){let g=Dt(o);if(g)n.add(g)}return{evidence:f,error:""}}catch(l){return{evidence:[],error:l.message||String(l)}}}function pl(t,e,r,n,a=[],l=[]){let i=n.filter((f)=>f?.content||f?.snippet).slice(0,10).map((f,o)=>({id:`F${o+1}`,title:f.title||"",url:f.finalUrl||f.url||"",snippet:T(f.content||f.snippet||"",3000)}));return["You are extracting compact research state from live multi-engine search results.","Create dense, non-overlapping learnings with exact names, numbers, dates, limitations, and caveats where available.","Also propose follow-up search queries that would most improve confidence or fill gaps.","",`Original research question: ${t}`,`Round queries: ${JSON.stringify(e,null,2)}`,`Question ledger: ${JSON.stringify(a,null,2)}`,`Extracted source evidence: ${JSON.stringify(l.slice(-12),null,2)}`,`Engine summaries: ${JSON.stringify(r,null,2)}`,`Fetched source snippets: ${JSON.stringify(i,null,2)}`,"","Respond ONLY with JSON wrapped in BEGIN_JSON / END_JSON markers:","BEGIN_JSON",JSON.stringify({learnings:["concise, information-dense learning"],answeredQuestions:[{id:"Q1",evidence:"brief evidence that closes this question",sourceIds:["S1"]}],newQuestions:["new sub-question discovered from the evidence"],followUpQueries:["specific next search query"],gaps:["important uncertainty or missing evidence"]},null,2),"END_JSON"].join(`
352
- `)}function hl(t,e,r,n=[],a=[]){let l=e.flatMap((o)=>o.learnings||[]),i=e.flatMap((o)=>o.gaps||[]),f=r.slice(0,12).map((o)=>({id:o.id,title:o.title,domain:o.domain,url:o.canonicalUrl,type:o.sourceType,engines:o.engines,fetch:o.fetch?.attempted?{ok:o.fetch.ok,snippet:T(o.fetch.snippet||"",1200),publishedTime:o.fetch.publishedTime||""}:void 0}));return["You are writing the final research report for an iterative deep-research run.","Produce a thorough markdown report organized into clear sections.","","Use the learnings and source registry below. Every substantive claim MUST be backed by an [S1] citation.",'Where engines disagree, surface the conflicting claims explicitly in the "differences" array.','Include a "Key Claims" structure that maps each distinct claim to its supporting source IDs.',"","Report structure:","1. ## Summary — A 2-4 sentence executive summary of findings","2. ## Key Findings — The main findings, organized by theme or question, each with inline citations","3. ## Areas of Disagreement — Where engines or sources conflict (if any)","4. ## Limitations & Caveats — Important qualifiers, gaps, or uncertainties","",`Original research question: ${t}`,`Learnings: ${JSON.stringify(l,null,2)}`,`Known gaps/caveats: ${JSON.stringify(i,null,2)}`,`Question ledger: ${JSON.stringify(n,null,2)}`,`Goal-based extracted evidence: ${JSON.stringify(a.slice(-20),null,2)}`,`Source registry: ${JSON.stringify(f,null,2)}`,"","Respond ONLY with JSON wrapped in BEGIN_JSON / END_JSON markers:","BEGIN_JSON",JSON.stringify({answer:"markdown report with sections and inline [S1] citations",agreement:{level:"high|medium|low|mixed|conflicting",summary:"one-sentence confidence summary"},differences:["notable disagreement or conflict between sources"],caveats:["important caveat or qualification"],claims:[{claim:"specific factual statement from the research",support:"strong|moderate|weak|conflicting",sourceIds:["S1","S2"]}],recommendedSources:["S1","S2"]},null,2),"END_JSON"].join(`
353
- `)}function wl(t,e=[],r=[],n=[]){let a=e.slice(0,12).map((o)=>({id:o.id,title:o.title,domain:o.domain,url:o.canonicalUrl,type:o.sourceType,engines:o.engines})),l=n.slice(-20),i=new Set;for(let o of l)for(let g of o.answers||[])if(g?.id)i.add(g.id);let f=(r||[]).filter((o)=>o.status!=="closed").map((o)=>({id:o.id,question:o.question}));return["You are writing the final research report from goal-based extracted evidence.","Per-round learnings were not produced, but the per-source evidence extraction step succeeded.","Synthesize a thorough markdown report using ONLY the evidence below. Every substantive claim MUST be backed by an [S1] citation.","","Report structure:","1. ## Summary — A 2-4 sentence executive summary of findings","2. ## Key Findings — The main findings, organized by theme or question, each with inline citations","3. ## Limitations & Caveats — Important qualifiers, gaps, or uncertainties","",`Original research question: ${t}`,`Per-source extracted evidence: ${JSON.stringify(l,null,2)}`,`Source registry: ${JSON.stringify(a,null,2)}`,`Questions already answered by the evidence: ${JSON.stringify(Array.from(i))}`,`Questions still open after this evidence: ${JSON.stringify(f)}`,"","Respond ONLY with JSON wrapped in BEGIN_JSON / END_JSON markers:","BEGIN_JSON",JSON.stringify({answer:"markdown report with sections and inline [S1] citations",agreement:{level:"high|medium|low|mixed|conflicting",summary:"one-sentence confidence summary"},differences:["notable disagreement or conflict between sources"],caveats:["important caveat or qualification"],claims:[{claim:"specific factual statement supported by the evidence",support:"strong|moderate|weak|conflicting",sourceIds:["S1","S2"]}],recommendedSources:["S1","S2"]},null,2),"END_JSON"].join(`
354
- `)}async function $l(t,{locale:e=null,short:r=!0}={}){let n=[Va,"all","--inline","--stdin","--fast"];if(!r)n.push("--full");if(e)n.push("--locale",e);return new Promise((a,l)=>{let i=Fa($t(),n,{stdio:["pipe","pipe","pipe"],env:{...process.env,GREEDY_SEARCH_RESEARCH_CHILD:"1"}});i.stdin.write(t),i.stdin.end();let f="",o="",g="";i.stdout.on("data",(h)=>f+=h),i.stderr.on("data",(h)=>{o+=h,g+=h.toString();let m=g.split(`
355
- `);g=m.pop()||"";for(let c of m)if(ml(c))process.stderr.write(`${c}
356
- `)});let p=setTimeout(()=>{i.kill(),l(Error(`research child search timed out for: ${t}`))},140000);i.on("close",(h)=>{if(clearTimeout(p),h!==0){l(Error(o.trim()||`search child exited with code ${h}`));return}try{a(JSON.parse(f.trim()))}catch{l(Error(`Invalid JSON from research child: ${f.slice(0,200)}`))}})})}function cl(t){let e=new Map;for(let r of t.flat()){let n=M(r.canonicalUrl||r.url);if(!n)continue;let a=e.get(n);if(!a){e.set(n,{...r,canonicalUrl:n});continue}a.engines=[...new Set([...a.engines||[],...r.engines||[]])],a.engineCount=a.engines.length,a.smartScore=Math.max(a.smartScore||0,r.smartScore||0)}return Array.from(e.values()).sort((r,n)=>{let a=X(n)-X(r);if(a!==0)return a;return(r.domain||"").localeCompare(n.domain||"")}).slice(0,12).map((r,n)=>({...r,id:`S${n+1}`}))}function ml(t){return/^PROGRESS:/.test(t)||/^\[greedysearch\]/.test(t)||/^\[(bing|perplexity|google|gemini|chatgpt|logically|semantic-scholar)\]/.test(t)||/^GreedySearch Chrome/.test(t)||/^Launching GreedySearch Chrome/.test(t)||/^Headless mode/.test(t)||/^Ready\.?$/.test(t)}function lt(t,e={}){return wt(t?.answer||"")||e}function bl(t,e){if(!t||!Array.isArray(e))return{cited:[],missing:[],unfetched:[],ok:!0};let r=/\b[SF](\d+)\b/g,n=new Set,a;while((a=r.exec(t))!==null)n.add(`S${a[1]}`),n.add(`F${a[1]}`);let l=new Map;for(let g of e){let p=g?.id;if(p)l.set(p,g)}let i=Array.from(n),f=[],o=[];for(let g of i){let p=l.get(g);if(!p){let h=g.match(/^(S|F)(\d+)$/);if(h){let m=parseInt(h[2],10)-1;if(m>=0&&m<e.length){let c=e[m];if(c){if(!(c.fetch?.ok||c.content&&c.content.length>100||c.contentChars&&c.contentChars>100))o.push(g);continue}}}f.push(g)}else if(!(p.fetch?.ok||p.content&&p.content.length>100||p.contentChars&&p.contentChars>100))o.push(g)}return{cited:i,missing:f,unfetched:o,ok:f.length===0}}function Cr({sources:t=[],fetchedSources:e=[],synthesis:r={},citationAudit:n=null,gaps:a=[],questions:l=[],rounds:i=[],qualityScore:f=0,qualityThreshold:o=8.5,maxSources:g=8,requireCitations:p=!0,requireQuestions:h=!0}={}){let m=e.filter((N)=>N?.fetch?.ok||(N?.contentChars||0)>100||String(N?.content||"").length>100),c=t.filter((N)=>["official-docs","repo","maintainer-blog","academic"].includes(String(N?.sourceType||""))),y=Array.isArray(r?.claims)?r.claims:[],b=n?n.cited?.length||0:0,w=ie(l),k=(l||[]).filter((N)=>!N.createdRound||N.reason==="Original research question"),C=ie(k),_=Math.min(4,Math.max(2,Number(g)||8)),s={roundsRun:i.length>=1,fetchedSources:m.length>=_,primarySources:c.length>=1,qualityScore:f>=Math.min(o,8),claimsExtracted:!p||y.length>0,citationsPresent:!p||b>0,citationsValid:!p||n?.ok===!0,unfetchedCitations:!p||(n?.unfetched||[]).length===0,requiredQuestionsClosed:!h||C.open===0};return{floorMet:Object.values(s).every(Boolean),checks:s,metrics:{fetchedOk:m.length,primarySources:c.length,claims:y.length,cited:b,gaps:a.length,openQuestions:w.open,closedQuestions:w.closed,totalQuestions:w.total,openRequiredQuestions:C.open,closedRequiredQuestions:C.closed,totalRequiredQuestions:C.total,qualityScore:f,minFetched:_}}}function Nr(t,e){let r=new Map;for(let n of e||[]){let a=M(n?.canonicalUrl||n?.finalUrl||n?.url);if(a&&n?.id)r.set(a,n.id)}return(t||[]).map((n,a)=>{let l=M(n?.finalUrl||n?.canonicalUrl||n?.url);return{...n,id:n?.id||r.get(l)||`F${a+1}`}})}function yl(t){return[{id:"Q1",question:T(A(t),320),status:"open",reason:"Original research question",evidence:[],sourceIds:[]}]}function _l(t){let e=0;for(let r of t||[]){let n=Number.parseInt(String(r.id||"").replace(/^Q/i,""),10);if(Number.isFinite(n))e=Math.max(e,n)}return`Q${e+1}`}function Lr(t,e){let r=A(e).toLowerCase();return(t||[]).find((n)=>n.question?.toLowerCase()===r||Et(n.question||"",r)>=0.82)}function ne(t,e,{reason:r="",round:n=null}={}){let a=T(A(e),320);if(!a)return null;let l=Lr(t,a);if(l)return l;let i={id:_l(t),question:a,status:"open",reason:T(r,240),createdRound:n,evidence:[],sourceIds:[]};return t.push(i),i}function jt(t,e,{evidence:r="",sourceIds:n=[],round:a=null}={}){let l=t.find((i)=>i.id===e)||Lr(t,e);if(!l)return null;if(l.status="closed",l.closedRound=l.closedRound||a,r)l.evidence=B([...l.evidence||[],r],4);if(Array.isArray(n))l.sourceIds=B([...l.sourceIds||[],...n],8);return l}function ie(t){let e=t.length,r=t.filter((n)=>n.status==="closed").length;return{total:e,closed:r,open:Math.max(0,e-r)}}function vt(t,{roundNumber:e,actions:r=[],learningPayload:n={}}={}){for(let o of r){let g=o?.action||o,p=g?.researchGoal&&g.researchGoal!=="Original user query"?g.researchGoal:g?.query||g?.url||"";if(p)ne(t,p,{reason:"Planned research action",round:e})}let a=5,l=t.filter((o)=>o.status==="open"&&o.reason==="Discovered gap/follow-up");if(l.length>a){let o=l.sort((g,p)=>(g.createdRound||0)-(p.createdRound||0)).slice(0,l.length-a);for(let g of o)g.status="resolved",g.closedRound=e,g.evidence=B([...g.evidence||[],"Auto-resolved to cap open-question ledger"],4)}let i=Array.isArray(n.answeredQuestions)?n.answeredQuestions:[];for(let o of i){if(typeof o==="string"){jt(t,o,{round:e});continue}let g=o?.id||o?.question;if(!g&&o?.question){let p=ne(t,o.question,{reason:"Answered during learning extraction",round:e});if(p)jt(t,p.id,{round:e});continue}jt(t,g,{evidence:o?.evidence||o?.answer||"",sourceIds:Array.isArray(o?.sourceIds)?o.sourceIds:[],round:e})}let f=Array.isArray(n.newQuestions)?n.newQuestions:[];for(let o of f)ne(t,o,{reason:"Discovered gap/follow-up",round:e});return t}function kl(t,e){if(!Array.isArray(t)||t.length===0)return[];let r=["arxiv.org","semanticscholar.org","doi.org"],n=new Set,a=[];for(let l of t){let i=l?.canonicalUrl||l?.finalUrl||l?.url||"";if(!i)continue;let f="";try{f=new URL(i).hostname.toLowerCase().replace(/^www\./,"")}catch{continue}if(!r.some((g)=>f===g||f.endsWith(`.${g}`)))continue;if(e.has(i)||n.has(i))continue;n.add(i);let o=i.includes("/pdf/")?i.replace(/\/pdf\//,"/html/").replace(/\.pdf$/i,""):i;a.push({url:o,label:l?.title||l?.id||f})}return a.slice(0,2)}function sl(t,e,r){if(!e?.answer||r?.ok!==!0)return t;let n=Array.isArray(e.claims)?e.claims:[],a=Array.isArray(r.cited)?r.cited:[];if(n.length===0||a.length===0)return t;for(let l of t){if(l.status==="closed")continue;let i=null,f=0;for(let o of n){let g=Et(l.question||"",o.claim||"");if(g>f)f=g,i=o}if(l.id==="Q1"||f>=0.18)jt(t,l.id,{evidence:i?.claim||"Answered in final cited synthesis",sourceIds:Array.isArray(i?.sourceIds)?i.sourceIds:a.slice(0,4)})}return t}function vl(t){if(!t.length)return"No tracked questions.";return t.map((e)=>{let r=e.sourceIds?.length?` (${e.sourceIds.join(", ")})`:"";return`- [${e.status==="closed"?"x":" "}] ${e.id}: ${e.question}${r}`}).join(`
357
- `)}function ae(t,e="None recorded."){let r=B(t);return r.length?r.map((n)=>`- ${n}`).join(`
358
- `):e}async function jl({query:t,rounds:e,sources:r,fetchedSources:n,evidenceItems:a=[],synthesis:l,citationAudit:i,floor:f,manifest:o,allGaps:g=[],questions:p=[],outDir:h=null}){let m=new Date().toISOString().replaceAll(/[:.]/g,"-").slice(0,19),c=h||E(Za,`${m}_${Ba(t)}`),y=E(c,"reports"),b=E(c,"sources"),w=E(c,"data");te(y,{recursive:!0}),te(b,{recursive:!0}),te(w,{recursive:!0});let k=await le(n,b),C=B([...g,...e.flatMap((_)=>_.gaps||[])]);return W(E(c,"STATUS.md"),[f.floorMet?"STATUS: DONE":"STATUS: PARTIAL","",`Query: ${t}`,`Stop reason: ${o.terminationReason||"max_rounds"}`,"","## Deterministic floor checks",...Object.entries(f.checks).map(([_,s])=>`- [${s?"x":" "}] ${_}`),"","## Questions",vl(p),"","## Open gaps",ae(C),""].join(`
359
- `),"utf8"),W(E(c,"OUTLINE.md"),["# Research bundle outline","","- `reports/SUMMARY.md` final cited report","- `reports/CLAIMS.md` extracted claims with support/source IDs","- `reports/EVIDENCE.md` goal-based source evidence","- `reports/GAPS.md` remaining caveats and uncertainties","- `sources/` fetched source markdown files","- `data/manifest.json` machine-readable run metadata","- `data/rounds.json` per-round actions/learnings/gaps","- `data/sources.json` ranked source registry","- `data/questions.json` open/closed question ledger",""].join(`
360
- `),"utf8"),W(E(y,"SUMMARY.md"),String(l.answer||""),"utf8"),W(E(y,"CLAIMS.md"),["# Key claims","",...Array.isArray(l.claims)&&l.claims.length?l.claims.map((_)=>{let s=Array.isArray(_.sourceIds)?_.sourceIds.join(", "):"";return`- ${_.claim||""} (${_.support||"support unknown"}${s?`; ${s}`:""})`}):["No structured claims were extracted."],""].join(`
361
- `),"utf8"),W(E(y,"EVIDENCE.md"),["# Extracted evidence","",...a.length?a.map((_)=>[`## ${_.sourceId||_.url||"Source"}`,_.url?`<${_.url}>`:"",_.rational?`**Rational:** ${_.rational}`:"",_.evidence?`**Evidence:** ${_.evidence}`:"",_.summary?`**Summary:** ${_.summary}`:"",""].filter(Boolean).join(`
435
+ ${f.map((l)=>`- ${l}`).join(`
436
+ `)}`:"",r,a,"","Respond ONLY with JSON wrapped in BEGIN_JSON / END_JSON markers:","BEGIN_JSON",JSON.stringify({actions:[{type:"search",query:"specific search query",researchGoal:"what this action should clarify"},{type:"fetchUrl",url:"https://example.com/docs/relevant-page",researchGoal:"extract specific information from this page"}]},null,2),"END_JSON"].join(`
437
+ `)}function Sf(t){if(!t||typeof t!=="object")return null;let n=t.type,f=H(t.researchGoal||"",320);if(n==="search"){if(t.query==null)return null;let p=c(t.query);return p?{type:"search",query:p,researchGoal:f}:null}if(n==="fetchUrl"){if(t.url==null)return null;let p=V(t.url);return p?{type:"fetchUrl",url:p,researchGoal:f}:null}return null}async function Fa(t,{locale:n=null,short:f=!0,usedQueries:p,usedUrls:g,maxChars:r=8000}={}){if(t.type==="search"){let a=c(t.query).toLowerCase();p.add(a);try{let l=await oa(t.query,{locale:n,short:f}),w=At(l,t.query);return{ok:!0,action:t,result:l,sources:w}}catch(l){return{ok:!1,action:t,error:l.message,sources:[]}}}if(t.type==="fetchUrl"){let a=V(t.url);if(g.has(a))return{ok:!1,action:t,error:`URL already fetched: ${a}`,sources:[]};try{let l=await Ga(a,r);g.add(a);let w=Wa(a),$={id:"",canonicalUrl:l.finalUrl||a,displayUrl:l.url||a,domain:w,title:l.title||a,engines:["fetch"],engineCount:1,perEngine:{},sourceType:tn(w,l.title||"",l.finalUrl||a),isOfficial:!1,smartScore:0,fetch:{attempted:!0,ok:!l.error&&(l.contentChars||0)>100,status:l.status||null,finalUrl:l.finalUrl||a,content:l.content||"",contentChars:l.contentChars||0,snippet:l.snippet||"",error:l.error||""}};return{ok:!0,action:t,result:null,sources:[$],fetchResult:{id:$.id,url:a,finalUrl:l.finalUrl||a,title:l.title||"",content:l.content||"",contentChars:l.contentChars||0,snippet:l.snippet||"",status:l.status||null,error:l.error||"",source:l.source||"http",duration:l.duration||0}}}catch(l){return{ok:!1,action:t,error:l.message,sources:[]}}}return{ok:!1,action:t,error:`Unknown action type: ${t.type}`,sources:[]}}async function Ga(t,n){let{fetchSourceContent:f}=await Promise.resolve().then(() => (Xt(),Nn));return await f(t,n)}function Wa(t){try{return new URL(t).hostname.toLowerCase().replace(/^www\./,"")}catch{return""}}async function Va(t,n){let f=[],{parseGitHubUrl:p}=await Promise.resolve().then(() => (Uf(),Bf));for(let g of t){if(g.type!=="fetchUrl"){f.push(g);continue}let r=p(g.url);if(!r||r.type!=="root"){f.push(g);continue}let{owner:a,repo:l}=r,w=`https://github.com/${a}/${l}`;if(n.has(w))continue;let $=[w],_=[`${w}/blob/main/CONTRIBUTING.md`,`${w}/blob/master/CONTRIBUTING.md`,`${w}/blob/main/CHANGELOG.md`,`${w}/blob/master/CHANGELOG.md`,`${w}/blob/main/docs/README.md`];for(let e of _){if($.length>=3)break;if(!n.has(e))$.push(e)}for(let e of $)f.push({type:"fetchUrl",url:e,researchGoal:g.researchGoal||`Fetch GitHub content for ${a}/${l}`})}return f}function ma(t,n){let f=ft(t?.answer||"")||{},p=Array.isArray(f?.actions)?f.actions:[],g=[];for(let r of p){let a=Sf(r);if(a&&g.length<n)g.push(a)}return g}function Ja(t){return(t||[]).map((n)=>({type:"search",query:typeof n==="string"?n:n.query,researchGoal:typeof n==="string"?"":n.researchGoal||""})).filter((n)=>n.query)}function yt(t){return V(t?.finalUrl||t?.canonicalUrl||t?.url||"")||t?.id||""}function cf(t,n){let f=Array.isArray(t?.extractions)?t.extractions:[],p=new Map,g=new Map;for(let r of n||[]){if(r?.id)g.set(String(r.id),r);let a=yt(r);if(a)p.set(a,r)}return f.map((r)=>{let a=g.get(String(r?.sourceId||""))||p.get(V(r?.url||"")||""),l=String(r?.sourceId||a?.id||""),w=V(r?.url||a?.finalUrl||a?.url||""),$=Array.isArray(r?.answers)?r.answers.map((_)=>({id:String(_?.id||""),evidence:H(_?.evidence||"",500),sourceIds:[l].filter(Boolean)})).filter((_)=>_.id):[];return{sourceId:l,url:w,title:a?.title||r?.title||"",rational:H(r?.rational||"",700),evidence:H(r?.evidence||"",1600),summary:H(r?.summary||"",700),answers:$,newQuestions:rt(r?.newQuestions||[],6)}}).filter((r)=>r.sourceId||r.url||r.summary||r.evidence)}function Za(t,n,f,p=new Set){let g=(n||[]).filter((a)=>a.status!=="closed").slice(0,12).map((a)=>({id:a.id,question:a.question})),r=(f||[]).filter((a)=>a?.content||a?.snippet).filter((a)=>!p.has(yt(a))).slice(0,6).map((a,l)=>({id:a.id||`F${l+1}`,title:a.title||"",url:a.finalUrl||a.url||a.canonicalUrl||"",content:H(a.content||a.snippet||"",5000)}));return["You are doing goal-based evidence extraction for an iterative research run.","For each source, extract only information that helps answer the open questions.","Use original wording/details where useful. Do not invent answers; leave questions open if evidence is insufficient.","If a source answers one or more tracked questions, identify those question IDs explicitly.","Also propose genuinely new sub-questions discovered from the evidence.","",`Original research question: ${t}`,`Open question ledger: ${JSON.stringify(g,null,2)}`,`Fetched sources: ${JSON.stringify(r,null,2)}`,"","Respond ONLY with JSON wrapped in BEGIN_JSON / END_JSON markers:","BEGIN_JSON",JSON.stringify({extractions:[{sourceId:"S1",url:"https://example.com/source",rational:"why this source matters for the goal",evidence:"specific quoted/paraphrased evidence with numbers, dates, caveats",summary:"concise contribution to the research question",answers:[{id:"Q1",evidence:"brief evidence that closes the question"}],newQuestions:["new sub-question raised by this source"]}]},null,2),"END_JSON"].join(`
438
+ `)}async function Zf({query:t,questions:n,fetchedSources:f,extractedSourceKeys:p}){let g=(f||[]).filter((r)=>(r?.content||r?.snippet)&&!p.has(yt(r)));if(g.length===0)return{evidence:[],error:""};try{let r=await X(Za(t,n,g,p),{timeoutMs:120000}),a=Ht(r,{extractions:[]}),l=cf(a,g);for(let w of g){let $=yt(w);if($)p.add($)}return{evidence:l,error:""}}catch(r){return{evidence:[],error:r.message||String(r)}}}function Ka(t,n,f,p,g,r,a=[]){let l=(n||[]).filter((R)=>R.status!=="closed").slice(0,12).map((R)=>({id:R.id,question:R.question})),w=(g||[]).filter((R)=>R?.content||R?.snippet),$=(r||[]).filter((R)=>R?.content||R?.snippet),_=({extractionCount:R,extractionLimit:y,learningCount:j,learningLimit:I})=>{let M=w.slice(0,R).map((k,F)=>({id:k.id||`F${F+1}`,title:k.title||"",url:k.finalUrl||k.url||k.canonicalUrl||"",content:H(k.content||k.snippet||"",y)})),A=$.slice(0,j).map((k,F)=>({id:`F${F+1}`,title:k.title||"",url:k.finalUrl||k.url||"",snippet:H(k.content||k.snippet||"",I)}));return["You are doing two combined research tasks for one round of an iterative research run. Perform BOTH tasks and return a single combined JSON object.","","TASK A — Goal-based evidence extraction:","For each source under 'Sources for evidence extraction', extract only information that helps answer the open questions.","Use original wording/details where useful. Do not invent answers; leave questions open if evidence is insufficient.","If a source answers one or more tracked questions, identify those question IDs explicitly.","Also propose genuinely new sub-questions discovered from the evidence.","","TASK B — Compact research-state learning extraction:","Using the round queries, question ledger, extracted source evidence, engine summaries, and fetched source snippets below, create dense, non-overlapping learnings with exact names, numbers, dates, limitations, and caveats where available.","Also propose follow-up search queries that would most improve confidence or fill gaps.","",`Original research question: ${t}`,`Open question ledger: ${JSON.stringify(l)}`,`Round queries: ${JSON.stringify(f)}`,`Question ledger: ${JSON.stringify(n)}`,`Extracted source evidence so far: ${JSON.stringify(a.slice(-12))}`,`Engine summaries: ${JSON.stringify(p)}`,`Sources for evidence extraction (Task A): ${JSON.stringify(M)}`,`Fetched source snippets (Task B context): ${JSON.stringify(A)}`,"","Respond ONLY with JSON wrapped in BEGIN_JSON / END_JSON markers, combining both tasks into one object:","BEGIN_JSON",JSON.stringify({extractions:[{sourceId:"S1",url:"https://example.com/source",rational:"why this source matters for the goal",evidence:"specific quoted/paraphrased evidence with numbers, dates, caveats",summary:"concise contribution to the research question",answers:[{id:"Q1",evidence:"brief evidence that closes the question"}],newQuestions:["new sub-question raised by this source"]}],learnings:["concise, information-dense learning"],answeredQuestions:[{id:"Q1",evidence:"brief evidence that closes this question",sourceIds:["S1"]}],newQuestions:["new sub-question discovered from the evidence"],followUpQueries:["specific next search query"],gaps:["important uncertainty or missing evidence"]},null,2),"END_JSON"].join(`
439
+ `)},e=Math.min(4,w.length),E=3000,h=Math.min(6,$.length),b=2000,D=_({extractionCount:e,extractionLimit:E,learningCount:h,learningLimit:b}),v=!1,P=600;while(D.length>ya){if(E>P||b>P)E=Math.max(P,Math.floor(E/2)),b=Math.max(P,Math.floor(b/2));else if(h>1)h-=1;else if(e>1)e-=1;else if(E>1||b>1)E=Math.max(1,Math.floor(E/2)),b=Math.max(1,Math.floor(b/2));else throw Error(`[greedysearch] evidence/learning prompt exceeds Gemini input cap after source trimming: ${D.length} chars`);v=!0,D=_({extractionCount:e,extractionLimit:E,learningCount:h,learningLimit:b})}if(v)console.error(`[greedysearch] evidence/learning prompt trimmed to fit Gemini input cap: ${D.length} chars`);return D}async function Xa({query:t,questions:n,fetchedSources:f,extractedSourceKeys:p,roundQueries:g,searchSummaries:r,evidenceItems:a=[]}){let l=(f||[]).filter((E)=>(E?.content||E?.snippet)&&!p.has(yt(E))),w=[],$="",_={learnings:[],followUpQueries:[],gaps:[]},e="";try{let E=await X(Ka(t,n,g,r,l,f,a),{timeoutMs:180000}),h=Ht(E,{});w=cf(h,l);for(let b of l){let D=yt(b);if(D)p.add(D)}_={..._,...h}}catch(E){let h=E.message||String(E);$=h,e=h}return{evidence:w,evidenceError:$,learningPayload:_,learningError:e}}function An(t,n,f,p=[],g=[]){let r=n.flatMap((w)=>w.learnings||[]),a=n.flatMap((w)=>w.gaps||[]),l=f.slice(0,12).map((w)=>({id:w.id,title:w.title,domain:w.domain,url:w.canonicalUrl,type:w.sourceType,engines:w.engines,fetch:w.fetch?.attempted?{ok:w.fetch.ok,snippet:H(w.fetch.snippet||"",1200),publishedTime:w.fetch.publishedTime||""}:void 0}));return["You are writing the final research report for an iterative deep-research run.","Produce a thorough markdown report organized into clear sections.","","Use the learnings and source registry below. Every substantive claim MUST be backed by an [S1] citation.",'Where engines disagree, surface the conflicting claims explicitly in the "differences" array.','Include a "Key Claims" structure that maps each distinct claim to its supporting source IDs.',"","Report structure:","1. ## Summary — A 2-4 sentence executive summary of findings","2. ## Key Findings — The main findings, organized by theme or question, each with inline citations","3. ## Areas of Disagreement — Where engines or sources conflict (if any)","4. ## Limitations & Caveats — Important qualifiers, gaps, or uncertainties","",`Original research question: ${t}`,`Learnings: ${JSON.stringify(r,null,2)}`,`Known gaps/caveats: ${JSON.stringify(a,null,2)}`,`Question ledger: ${JSON.stringify(p,null,2)}`,`Goal-based extracted evidence: ${JSON.stringify(g.slice(-20),null,2)}`,`Source registry: ${JSON.stringify(l,null,2)}`,"","Respond ONLY with JSON wrapped in BEGIN_JSON / END_JSON markers:","BEGIN_JSON",JSON.stringify({answer:"markdown report with sections and inline [S1] citations",agreement:{level:"high|medium|low|mixed|conflicting",summary:"one-sentence confidence summary"},differences:["notable disagreement or conflict between sources"],caveats:["important caveat or qualification"],claims:[{claim:"specific factual statement from the research",support:"strong|moderate|weak|conflicting",sourceIds:["S1","S2"]}],recommendedSources:["S1","S2"]},null,2),"END_JSON"].join(`
440
+ `)}function Tn(t,n=[],f=[],p=[]){let g=n.slice(0,12).map((w)=>({id:w.id,title:w.title,domain:w.domain,url:w.canonicalUrl,type:w.sourceType,engines:w.engines})),r=p.slice(-20),a=new Set;for(let w of r)for(let $ of w.answers||[])if($?.id)a.add($.id);let l=(f||[]).filter((w)=>w.status!=="closed").map((w)=>({id:w.id,question:w.question}));return["You are writing the final research report from goal-based extracted evidence.","Per-round learnings were not produced, but the per-source evidence extraction step succeeded.","Synthesize a thorough markdown report using ONLY the evidence below. Every substantive claim MUST be backed by an [S1] citation.","","Report structure:","1. ## Summary — A 2-4 sentence executive summary of findings","2. ## Key Findings — The main findings, organized by theme or question, each with inline citations","3. ## Limitations & Caveats — Important qualifiers, gaps, or uncertainties","",`Original research question: ${t}`,`Per-source extracted evidence: ${JSON.stringify(r,null,2)}`,`Source registry: ${JSON.stringify(g,null,2)}`,`Questions already answered by the evidence: ${JSON.stringify(Array.from(a))}`,`Questions still open after this evidence: ${JSON.stringify(l)}`,"","Respond ONLY with JSON wrapped in BEGIN_JSON / END_JSON markers:","BEGIN_JSON",JSON.stringify({answer:"markdown report with sections and inline [S1] citations",agreement:{level:"high|medium|low|mixed|conflicting",summary:"one-sentence confidence summary"},differences:["notable disagreement or conflict between sources"],caveats:["important caveat or qualification"],claims:[{claim:"specific factual statement supported by the evidence",support:"strong|moderate|weak|conflicting",sourceIds:["S1","S2"]}],recommendedSources:["S1","S2"]},null,2),"END_JSON"].join(`
441
+ `)}async function oa(t,{locale:n=null,short:f=!0}={}){let p=[Pa,"all","--inline","--stdin","--fast"];if(!f)p.push("--full");if(n)p.push("--locale",n);return new Promise((g,r)=>{let a=Ca(jt(),p,{stdio:["pipe","pipe","pipe"],env:{...process.env,GREEDY_SEARCH_RESEARCH_CHILD:"1"}});a.stdin.write(t),a.stdin.end();let l="",w="",$="";a.stdout.on("data",(e)=>l+=e),a.stderr.on("data",(e)=>{w+=e,$+=e.toString();let E=$.split(`
442
+ `);$=E.pop()||"";for(let h of E)if(xa(h))process.stderr.write(`${h}
443
+ `)});let _=setTimeout(()=>{a.kill(),r(Error(`research child search timed out for: ${t}`))},140000);a.on("close",(e)=>{if(clearTimeout(_),e!==0){r(Error(w.trim()||`search child exited with code ${e}`));return}try{g(JSON.parse(l.trim()))}catch{r(Error(`Invalid JSON from research child: ${l.slice(0,200)}`))}})})}function Ba(t){let n=new Map;for(let f of t.flat()){let p=V(f.canonicalUrl||f.url);if(!p)continue;let g=n.get(p);if(!g){n.set(p,{...f,canonicalUrl:p});continue}g.engines=[...new Set([...g.engines||[],...f.engines||[]])],g.engineCount=g.engines.length,g.smartScore=Math.max(g.smartScore||0,f.smartScore||0)}return Array.from(n.values()).sort((f,p)=>{let g=ht(p)-ht(f);if(g!==0)return g;return(f.domain||"").localeCompare(p.domain||"")}).slice(0,12).map((f,p)=>({...f,id:`S${p+1}`}))}var Ua=Pt.join("|"),Qa=new RegExp(`^\\[(${Ua})\\]`);function xa(t){return/^PROGRESS:/.test(t)||/^\[greedysearch\]/.test(t)||Qa.test(t)||/^GreedySearch Chrome/.test(t)||/^Launching GreedySearch Chrome/.test(t)||/^Headless mode/.test(t)||/^Ready\.?$/.test(t)}function Ht(t,n={}){return ft(t?.answer||"")||n}function kn(t,n){if(!t||!Array.isArray(n))return{cited:[],missing:[],unfetched:[],ok:!0};let f=/\b[SF](\d+)\b/g,p=new Set,g;while((g=f.exec(t))!==null)p.add(`S${g[1]}`),p.add(`F${g[1]}`);let r=new Map;for(let $ of n){let _=$?.id;if(_)r.set(_,$)}let a=Array.from(p),l=[],w=[];for(let $ of a){let _=r.get($);if(!_){let e=$.match(/^(S|F)(\d+)$/);if(e){let E=parseInt(e[2],10)-1;if(E>=0&&E<n.length){let h=n[E];if(h){if(!(h.fetch?.ok||h.content&&h.content.length>100||h.contentChars&&h.contentChars>100))w.push($);continue}}}l.push($)}else if(!(_.fetch?.ok||_.content&&_.content.length>100||_.contentChars&&_.contentChars>100))w.push($)}return{cited:a,missing:l,unfetched:w,ok:l.length===0}}async function za(t,{timeoutMs:n=6000,concurrency:f=4}={}){let p=Math.max(1,Math.floor(f||1)),g=(t||[]).filter((E)=>E?.id&&(E?.canonicalUrl||E?.finalUrl||E?.url));if(g.length===0)return{reachable:[],dead:[],skipped:[],ok:!0};let r=[],a=[],l=[],w=Array(g.length),$=0;async function _(){while(!0){let E=$++;if(E>=g.length)return;let h=g[E];try{let b=h.fetch?.finalUrl||h.canonicalUrl||h.finalUrl||h.url;if(!b){w[E]={id:h.id,url:"",status:"skipped"};continue}try{let D=new URL(b);if(D.protocol!=="http:"&&D.protocol!=="https:"){w[E]={id:h.id,url:b,status:"skipped"};continue}}catch{w[E]={id:h.id,url:b,status:"skipped"};continue}try{let D=new AbortController,v=setTimeout(()=>D.abort(),n);try{let P=await fetch(b,{method:"HEAD",redirect:"follow",signal:D.signal,headers:{"User-Agent":"Mozilla/5.0 (compatible; GreedySearch/2.0; +https://github.com/apmantza/greedysearch-dm)"}});clearTimeout(v);let R=P.status>=200&&P.status<400,y=[401,403,405,429].includes(P.status),j="dead";if(R)j="reachable";else if(y)j="skipped";w[E]={id:h.id,url:b,status:j,httpStatus:P.status,reason:y?"bot-protected-or-head-disallowed":void 0}}catch(P){clearTimeout(v),w[E]={id:h.id,url:b,status:"dead",error:P.name==="AbortError"?"timeout":P.message}}}catch(D){w[E]={id:h.id,url:b,status:"dead",error:D.message}}}catch(b){w[E]={id:"?",url:"",status:"dead",error:b?.message||"unknown"}}}}let e=Math.min(g.length,p);await Promise.all(Array.from({length:e},()=>_()));for(let E of w)if(E.status==="reachable")r.push(E);else if(E.status==="dead")a.push(E);else l.push(E);return{reachable:r,dead:a,skipped:l,ok:a.length===0}}async function Hn(t,n=null){process.stderr.write(`PROGRESS:research:check-urls
444
+ `);try{let f=new Set(n?.cited||[]),p=f.size?(t||[]).filter((r)=>f.has(r?.id)):t,g=await za(p,{timeoutMs:6000,concurrency:4});if(!g.ok)process.stderr.write(`[greedysearch] ${g.dead.length} dead citation URL(s) detected
445
+ `);return g}catch(f){return process.stderr.write(`[greedysearch] URL reachability check failed: ${f.message}
446
+ `),null}}function Bt({sources:t=[],fetchedSources:n=[],synthesis:f={},citationAudit:p=null,gaps:g=[],questions:r=[],rounds:a=[],qualityScore:l=0,qualityThreshold:w=8.5,maxSources:$=8,requireCitations:_=!0,requireQuestions:e=!0}={}){let E=n.filter((A)=>A?.fetch?.ok||(A?.contentChars||0)>100||String(A?.content||"").length>100),h=t.filter((A)=>["official-docs","repo","maintainer-blog","academic"].includes(String(A?.sourceType||""))),b=Array.isArray(f?.claims)?f.claims:[],D=p?p.cited?.length||0:0,v=Zn(r),P=(r||[]).filter((A)=>!A.createdRound||A.reason==="Original research question"),R=Zn(P),y=(a||[]).length,j=Math.min(4,Math.max(2,Number($)||8)),I=y<=1?Math.min(2,j):j,M={roundsRun:a.length>=1,fetchedSources:E.length>=I,primarySources:h.length>=1,qualityScore:l>=Math.min(w,8)||_&&b.length>0&&D>0,claimsExtracted:!_||b.length>0,citationsPresent:!_||D>0,citationsValid:!_||p?.ok===!0,unfetchedCitations:!_||(p?.unfetched||[]).length===0,requiredQuestionsClosed:!e||R.open===0};return{floorMet:Object.values(M).every(Boolean),checks:M,metrics:{fetchedOk:E.length,primarySources:h.length,claims:b.length,cited:D,gaps:g.length,openQuestions:v.open,closedQuestions:v.closed,totalQuestions:v.total,openRequiredQuestions:R.open,closedRequiredQuestions:R.closed,totalRequiredQuestions:R.total,qualityScore:l,minFetched:I}}}function Qf(t,n){let f=new Map;for(let p of n||[]){let g=V(p?.canonicalUrl||p?.finalUrl||p?.url);if(g&&p?.id)f.set(g,p.id)}return(t||[]).map((p,g)=>{let r=V(p?.finalUrl||p?.canonicalUrl||p?.url);return{...p,id:p?.id||f.get(r)||`F${g+1}`}})}function Ln(t){return[{id:"Q1",question:H(c(t),320),status:"open",reason:"Original research question",evidence:[],sourceIds:[]}]}function Sa(t){let n=0;for(let f of t||[]){let p=Number.parseInt(String(f.id||"").replace(/^Q/i,""),10);if(Number.isFinite(p))n=Math.max(n,p)}return`Q${n+1}`}function df(t,n){let f=c(n).toLowerCase();return(t||[]).find((p)=>p.question?.toLowerCase()===f||Kn(p.question||"",f)>=0.82)}function Wn(t,n,{reason:f="",round:p=null}={}){let g=H(c(n),320);if(!g)return null;let r=df(t,g);if(r)return r;let a={id:Sa(t),question:g,status:"open",reason:H(f,240),createdRound:p,evidence:[],sourceIds:[]};return t.push(a),a}function Qt(t,n,{evidence:f="",sourceIds:p=[],round:g=null}={}){let r=t.find((a)=>a.id===n)||df(t,n);if(!r)return null;if(r.status="closed",r.closedRound=r.closedRound||g,f)r.evidence=rt([...r.evidence||[],f],4);if(Array.isArray(p))r.sourceIds=rt([...r.sourceIds||[],...p],8);return r}function Zn(t){let n=t.length,f=t.filter((p)=>p.status==="closed").length;return{total:n,closed:f,open:Math.max(0,n-f)}}function Ut(t,{roundNumber:n,actions:f=[],learningPayload:p={}}={}){for(let w of f){let $=w?.action||w,_=$?.researchGoal&&$.researchGoal!=="Original user query"?$.researchGoal:$?.query||$?.url||"";if(_)Wn(t,_,{reason:"Planned research action",round:n})}let g=5,r=t.filter((w)=>w.status==="open"&&w.reason==="Discovered gap/follow-up");if(r.length>g){let w=r.sort(($,_)=>($.createdRound||0)-(_.createdRound||0)).slice(0,r.length-g);for(let $ of w)$.status="resolved",$.closedRound=n,$.evidence=rt([...$.evidence||[],"Auto-resolved to cap open-question ledger"],4)}let a=Array.isArray(p.answeredQuestions)?p.answeredQuestions:[];for(let w of a){if(typeof w==="string"){Qt(t,w,{round:n});continue}let $=w?.id||w?.question;if(!$&&w?.question){let _=Wn(t,w.question,{reason:"Answered during learning extraction",round:n});if(_)Qt(t,_.id,{round:n});continue}Qt(t,$,{evidence:w?.evidence||w?.answer||"",sourceIds:Array.isArray(w?.sourceIds)?w.sourceIds:[],round:n})}let l=Array.isArray(p.newQuestions)?p.newQuestions:[];for(let w of l)Wn(t,w,{reason:"Discovered gap/follow-up",round:n});return t}function ca(t,n){if(!Array.isArray(t)||t.length===0)return[];let f=["arxiv.org","semanticscholar.org","doi.org"],p=new Set,g=[];for(let r of t){let a=r?.canonicalUrl||r?.finalUrl||r?.url||"";if(!a)continue;let l="";try{l=new URL(a).hostname.toLowerCase().replace(/^www\./,"")}catch{continue}if(!f.some(($)=>l===$||l.endsWith(`.${$}`)))continue;if(n.has(a)||p.has(a))continue;p.add(a);let w=a.includes("/pdf/")?a.replace(/\/pdf\//,"/html/").replace(/\.pdf$/i,""):a;g.push({url:w,label:r?.title||r?.id||l})}return g.slice(0,2)}function Yn(t,n,f){if(!n?.answer||f?.ok!==!0)return t;let p=Array.isArray(n.claims)?n.claims:[],g=Array.isArray(f.cited)?f.cited:[];if(p.length===0||g.length===0)return t;for(let r of t){if(r.status==="closed")continue;let a=null,l=0;for(let w of p){let $=Kn(r.question||"",w.claim||"");if($>l)l=$,a=w}if(r.id==="Q1"||l>=0.18)Qt(t,r.id,{evidence:a?.claim||"Answered in final cited synthesis",sourceIds:Array.isArray(a?.sourceIds)?a.sourceIds:g.slice(0,4)})}return t}function da(t){if(!t.length)return"No tracked questions.";return t.map((n)=>{let f=n.sourceIds?.length?` (${n.sourceIds.join(", ")})`:"";return`- [${n.status==="closed"?"x":" "}] ${n.id}: ${n.question}${f}`}).join(`
447
+ `)}function Vn(t,n="None recorded."){let f=rt(t);return f.length?f.map((p)=>`- ${p}`).join(`
448
+ `):n}function qa(t,{query:n,rounds:f,sources:p,fetchedSources:g,citationAudit:r,citationUrls:a,floor:l,manifest:w}){let $=(g||[]).filter((D)=>D?.contentChars>100||D?.fetch?.ok),_=(p||[]).filter((D)=>["official-docs","repo","maintainer-blog","academic"].includes(String(D?.sourceType||""))),e=new Set(r?.cited||[]),E=(p||[]).filter((D)=>e.has(D?.id)),h=[`# Provenance: ${n}`,"",`- **Date:** ${w?.startedAt||new Date().toISOString()}`,`- **Duration:** ${w?.durationMs?`${(w.durationMs/1000).toFixed(1)}s`:"unknown"}`,`- **Mode:** ${w?.terminationReason==="simple_single_pass"?"simple (single-pass)":"iterative"}`,`- **Rounds:** ${w?.rounds||f?.length||1}`,"","## Sources","",`- **Consulted:** ${p?.length||0}`,`- **Fetched successfully:** ${$.length}`,`- **Primary sources:** ${_.length}`,`- **Cited in report:** ${E.length}`,""];if(E.length>0){h.push("### Cited sources","");for(let D of E){let v=D.canonicalUrl||D.finalUrl||D.url||"",P=D.fetch?.ok?"✓":"✗";h.push(`- **${D.id}:** [${D.title||v}](${v}) (${D.sourceType||"unknown"}, fetched: ${P})`)}h.push("")}if(a&&(a.reachable.length>0||a.dead.length>0)){if(h.push("## URL reachability",""),a.dead.length>0){h.push(""),h.push("**Dead links:**");for(let D of a.dead)h.push(`- ${D.id}: ${D.url} (${D.httpStatus||D.error||"unknown"})`)}if(a.reachable.length>0)h.push(""),h.push(`**Reachable:** ${a.reachable.length}/${a.reachable.length+a.dead.length}`);h.push("")}let b=!r?"NOT CHECKED":r.ok&&(a?.ok??!0)?"PASS":r.ok===!1?"FAIL (missing citations)":"FAIL (dead links)";if(h.push("## Verification","",`- **Citations:** ${r?.ok?"PASS":`FAIL — missing: ${(r?.missing||[]).join(", ")}`}`,`- **URL reachability:** ${a?a.ok?"PASS":`FAIL — ${a.dead.length} dead`:"SKIPPED"}`,`- **Floor:** ${l?.floorMet?"PASS":"PARTIAL"}`,`- **Overall:** ${b}`,""),l?.checks){h.push("## Floor checks","");for(let[D,v]of Object.entries(l.checks))h.push(`- [${v?"x":" "}] ${D}`);h.push("")}J(Y(t,"provenance.md"),h.join(`
449
+ `),"utf8")}async function In({query:t,rounds:n,sources:f,fetchedSources:p,evidenceItems:g=[],synthesis:r,citationAudit:a,floor:l,manifest:w,allGaps:$=[],questions:_=[],citationUrls:e=null,outDir:E=null}){let h=new Date().toISOString().replaceAll(/[:.]/g,"-").slice(0,19),b=E||Y(Ra,`${h}_${Oa(t)}`),D=Y(b,"reports"),v=Y(b,"sources"),P=Y(b,"data");Mn(D,{recursive:!0}),Mn(v,{recursive:!0}),Mn(P,{recursive:!0});let R=await mn(p,v),y=rt([...$,...n.flatMap((j)=>j.gaps||[])]);J(Y(b,"STATUS.md"),[l.floorMet?"STATUS: DONE":"STATUS: PARTIAL","",`Query: ${t}`,`Stop reason: ${w.terminationReason||"max_rounds"}`,"","## Deterministic floor checks",...Object.entries(l.checks).map(([j,I])=>`- [${I?"x":" "}] ${j}`),"","## Questions",da(_),"","## Open gaps",Vn(y),""].join(`
450
+ `),"utf8"),J(Y(b,"OUTLINE.md"),["# Research bundle outline","","- `reports/SUMMARY.md` — final cited report","- `reports/CLAIMS.md` — extracted claims with support/source IDs","- `reports/EVIDENCE.md` — goal-based source evidence","- `reports/GAPS.md` — remaining caveats and uncertainties","- `provenance.md` — human-readable run metadata and verification","- `sources/` — fetched source markdown files","- `data/manifest.json` — machine-readable run metadata","- `data/rounds.json` — per-round actions/learnings/gaps","- `data/sources.json` — ranked source registry","- `data/questions.json` — open/closed question ledger",""].join(`
451
+ `),"utf8"),J(Y(D,"SUMMARY.md"),String(r.answer||""),"utf8"),J(Y(D,"CLAIMS.md"),["# Key claims","",...Array.isArray(r.claims)&&r.claims.length?r.claims.map((j)=>{let I=Array.isArray(j.sourceIds)?j.sourceIds.join(", "):"";return`- ${j.claim||""} (${j.support||"support unknown"}${I?`; ${I}`:""})`}):["No structured claims were extracted."],""].join(`
452
+ `),"utf8"),J(Y(D,"EVIDENCE.md"),["# Extracted evidence","",...g.length?g.map((j)=>[`## ${j.sourceId||j.url||"Source"}`,j.url?`<${j.url}>`:"",j.rational?`**Rational:** ${j.rational}`:"",j.evidence?`**Evidence:** ${j.evidence}`:"",j.summary?`**Summary:** ${j.summary}`:"",""].filter(Boolean).join(`
362
453
  `)):["No goal-based evidence was extracted."],""].join(`
363
- `),"utf8"),W(E(y,"GAPS.md"),["# Gaps and caveats","","## Caveats",ae(l.caveats||[]),"","## Research gaps",ae(C),""].join(`
364
- `),"utf8"),W(E(w,"manifest.json"),JSON.stringify({...o,floor:f,citationAudit:i},null,2),"utf8"),W(E(w,"rounds.json"),JSON.stringify(e,null,2),"utf8"),W(E(w,"sources.json"),JSON.stringify(r,null,2),"utf8"),W(E(w,"questions.json"),JSON.stringify(p,null,2),"utf8"),W(E(w,"evidence.json"),JSON.stringify(a,null,2),"utf8"),W(E(b,"index.md"),["# Source index","",...k.map((_)=>{let s=_.title||_.url,N=_.finalUrl||_.url,R=_.contentPath?` — ${_.contentPath}`:"";return`- ${_.id||"?"}: [${s}](${N})${R}`}),""].join(`
365
- `),"utf8"),{dir:c,statusPath:E(c,"STATUS.md"),summaryPath:E(y,"SUMMARY.md"),manifestPath:E(w,"manifest.json"),sourceCount:k.length,sourceFiles:k}}async function Cf({query:t,breadth:e=3,iterations:r=2,maxSources:n,locale:a=null,short:l=!1,qualityThreshold:i=8.5,writeBundle:f=process.env.GREEDY_RESEARCH_BUNDLE!=="0",researchOutDir:o=null}={}){let g=Ua({breadth:e,iterations:r,maxSources:n}),p=[],h=[],m=[],c=yl(t),y=null,b=[],w=[],k=[],C=new Set,_=new Set,s=new Set,N=[],R="max_rounds",Wr=new Date().toISOString(),Mr=Date.now(),fe=0,ge=0,oe=0,pe=[];process.stderr.write(`[greedysearch] Research mode: breadth ${g.breadth}, iterations ${g.iterations}, qualityThreshold ${i}, engines ${Jt.join(",")}, synthesizer gemini
366
- `);for(let v=0;v<g.iterations;v++){let D=v+1,J=Math.max(1,Math.ceil(g.breadth/2**v));if(process.stderr.write(`PROGRESS:research:round-${D}:planning
367
- `),!y)try{let $=await x(qa(t,J,h,m,[...s]),{timeoutMs:120000}),j=ll($,J);if(v===0)j.unshift({type:"search",query:t,researchGoal:"Original user query"});j=await al(j,s),y=j}catch($){process.stderr.write(`[greedysearch] Action planning failed, using fallback queries: ${$.message}
368
- `);let j=Ia(null,t,J,{includeOriginal:v===0,exclude:_});y=il(j)}let z=(y||[]).filter(($)=>{if($.type==="search"){let j=!Or($.query,_,{roundIndex:v,originalQuery:t});if(!j)process.stderr.write(`[greedysearch] Novelty gate rejected search: ${$.query}
369
- `);return j}if($.type==="fetchUrl"){let j=!s.has($.url);if(!j)process.stderr.write(`[greedysearch] Novelty gate rejected fetch: ${$.url}
370
- `);return j}return!1}).slice(0,J),we=kl(b,s);if(!z.some(($)=>$.type==="fetchUrl")&&we.length>0){let $=we[0];z.push({type:"fetchUrl",url:$.url,researchGoal:`Direct fetch of known academic source: ${$.label||$.url}`}),process.stderr.write(`[greedysearch] Forced fetchUrl for academic source: ${$.url}
371
- `)}let S=[];for(let $=0;$<z.length;$++){let j=z[$];process.stderr.write(`PROGRESS:research:round-${D}:action-${$+1}/${z.length}
372
- `),process.stderr.write(`[greedysearch] Action ${$+1}/${z.length} [${j.type}]: ${(j.query||j.url).slice(0,80)}
373
- `);let F=await tl(j,{locale:a,short:l,usedQueries:_,usedUrls:s,maxChars:8000});if(S.push(F),fe++,j.type==="search")ge++;if(j.type==="fetchUrl")oe++;if(!F.ok)pe.push({round:D,type:j.type,target:j.query||j.url,error:F.error}),process.stderr.write(`[greedysearch] Action failed: ${F.error}
374
- `)}let $e=S.filter(($)=>$.action.type==="search"),ce=S.filter(($)=>$.action.type==="fetchUrl");vt(c,{roundNumber:D,actions:S}),b=cl([b,$e.flatMap(($)=>$.sources||[]),ce.flatMap(($)=>$.sources||[])]);for(let $ of ce)if($.fetchResult)w.push($.fetchResult);w=Tr(w);let Ct=Math.max(0,g.maxSources-w.filter(($)=>$?.content||$?.contentChars>100).length);if(Ct>0&&b.length>0){process.stderr.write(`PROGRESS:research:round-${D}:fetching
375
- `);let $=await Ka(b,Math.min(Ct,b.length),8000,Math.min(3,Ct||1));w=Tr([...w,...$]),b=se(b,w)}w=Nr(w,b),process.stderr.write(`PROGRESS:research:round-${D}:evidence
376
- `);let u=await ol({query:t,questions:c,fetchedSources:w,extractedSourceKeys:C});if(u.error)process.stderr.write(`[greedysearch] Evidence extraction failed: ${u.error}
377
- `);k=[...k,...u.evidence];for(let $ of u.evidence)vt(c,{roundNumber:D,learningPayload:{answeredQuestions:$.answers||[],newQuestions:$.newQuestions||[]}});let dr=S.map(($)=>({query:$.action.query||$.action.url||"",researchGoal:$.action.researchGoal||""}));process.stderr.write(`PROGRESS:research:round-${D}:learning
378
- `);let d={learnings:[],followUpQueries:[],gaps:[]},me="";try{let $=await x(pl(t,dr,$e.map((j)=>({query:j.action.query,researchGoal:j.action.researchGoal,error:j.error||"",engines:ua(j.result)})),w,c,k),{timeoutMs:120000});d={...d,...lt($,d)}}catch($){me=$.message,process.stderr.write(`[greedysearch] Learning extraction failed: ${$.message}
379
- `)}let be=Array.isArray(d.learnings)?d.learnings.map(($)=>String($)).filter(Boolean).slice(0,8):[],Nt=Array.isArray(d.gaps)?d.gaps.map(($)=>String($)).filter(Boolean).slice(0,6):[];h=B([...h,...be]),m=B([...m,...Nt]),vt(c,{roundNumber:D,actions:[],learningPayload:d,gaps:Nt}),p.push({round:D,actions:S.map(($)=>({type:$.action.type,query:$.action.query||"",url:$.action.url||"",researchGoal:$.action.researchGoal||"",error:$.error||"",sourceCount:$.sources?.length||0})),learnings:be,gaps:Nt,evidence:u.evidence,evidenceError:u.error,learningError:me}),process.stderr.write(`PROGRESS:research:round-${D}:evaluating
380
- `);let L=await Sa(t,p,h,m,N);N.push(L.score),m=B([...m,...L.knowledgeGaps||[]]),vt(c,{roundNumber:D,gaps:L.knowledgeGaps||[]});let ye=Cr({sources:b,fetchedSources:w,gaps:m,questions:c,rounds:p,qualityScore:L.score,qualityThreshold:i,maxSources:g.maxSources,requireCitations:!1,requireQuestions:!1});if(process.stderr.write(`[greedysearch] Quality score round ${D}: ${L.score.toFixed(1)} (shouldContinue: ${L.shouldContinue}, floor: ${ye.floorMet})
381
- `),L.score>=i&&ye.floorMet&&(!L.shouldContinue||L.terminationReason==="quality_threshold")){R=L.terminationReason||"quality_threshold",process.stderr.write(`[greedysearch] Research floor reached (score: ${L.score.toFixed(1)}). Terminating early.
382
- `);break}let I=Math.max(1,Math.ceil(J/2)),H=(d.followUpQueries||[]).map(($)=>({type:"search",query:A(String($)),researchGoal:"Follow-up from learning extraction"})).filter(($)=>$.query&&$.query.toLowerCase()!==t.toLowerCase()).slice(0,I);if(H.length<I&&L.nextActions.length>0){let $=L.nextActions.map((F)=>Pr(F)).filter(Boolean);H=[...H,...$].slice(0,I)}if(H.length<I&&m.length>0){let $=za(m,t,_,I-H.length,v+1),j=$.map((F)=>({type:"search",query:F.query,researchGoal:F.researchGoal}));if(H=[...H,...j].slice(0,I),$.length>0)process.stderr.write(`[greedysearch] Generated ${$.length} gap-driven fallback actions.
383
- `)}y=H.length>=I?H:null}process.stderr.write(`PROGRESS:research:final-report
384
- `);let O={answer:h.length?h.map((v)=>`- ${v}`).join(`
385
- `):"Research completed, but no structured learnings were extracted.",agreement:{level:"mixed",summary:"Research synthesis fallback."},differences:[],caveats:[],claims:[],recommendedSources:b.slice(0,4).map((v)=>v.id),synthesized:!1};try{let v=await x(hl(t,p,b,c,k),{timeoutMs:180000}),D=lt(v,{}),J=Array.isArray(D?.claims)&&D.claims.length>0;O={...O,...D,rawAnswer:v.answer||"",geminiSources:v.sources||[],synthesized:J}}catch(v){process.stderr.write(`[greedysearch] Final report failed: ${v.message}
386
- `),O.error=v.message}if(!(O.synthesized===!0&&Array.isArray(O.claims)&&O.claims.length>0)&&k.length>0){process.stderr.write(`[greedysearch] Falling back to evidence-based synthesis (no per-round learnings).
387
- `);try{let v=wl(t,b,c,k),D=await x(v,{timeoutMs:180000}),J=lt(D,{});O={...O,...J,rawAnswer:D.answer||O.answer||"",geminiSources:D.sources||O.geminiSources||[],synthesized:!0,synthesisMode:"evidence_fallback"}}catch(v){process.stderr.write(`[greedysearch] Evidence-based synthesis failed: ${v.message}
388
- `),O.evidenceFallbackError=v.message}}let Ar=new Date().toISOString(),Rr=Date.now()-Mr,Jr=N.at(-1)||0;w=Nr(w,b),process.stderr.write(`PROGRESS:research:audit-citations
389
- `);let it=bl(O.answer||"",b);sl(c,O,it);let Q=Cr({sources:b,fetchedSources:w,synthesis:O,citationAudit:it,gaps:m,questions:c,rounds:p,qualityScore:Jr,qualityThreshold:i,maxSources:g.maxSources});if(Q.floorMet&&R==="max_rounds")R="done_floor_met";else if(!Q.floorMet&&R==="quality_threshold")R="max_rounds_floor_unmet";let he={startedAt:Wr,finishedAt:Ar,durationMs:Rr,engines:Jt,synthesizer:"gemini",rounds:p.length,actionsRun:fe,searches:ge,fetches:oe,sourcesFetched:w.filter((v)=>v?.contentChars>100).length,engineFailures:pe,terminationReason:R,floorMet:Q.floorMet},tt=null,ft;if(f){process.stderr.write(`PROGRESS:research:bundle
390
- `);try{tt=await jl({query:t,rounds:p,sources:b,fetchedSources:w,evidenceItems:k,synthesis:O,citationAudit:it,floor:Q,manifest:he,allGaps:m,questions:c,outDir:o}),ft=tt.sourceFiles,delete tt.sourceFiles}catch(v){tt={error:v.message||String(v)},ft=await le(w)}}else ft=await le(w);return process.stderr.write(`PROGRESS:research:done
391
- `),{query:t,_research:{mode:"iterative",breadth:g.breadth,iterations:g.iterations,maxSources:g.maxSources,rounds:p,learnings:h,gaps:m,evidence:k,questions:c,questionProgress:ie(c),qualityHistory:N,terminationReason:R,qualityThreshold:i,floor:Q,bundle:tt,manifest:he},_citationAudit:it,_sources:b,_fetchedSources:ft,_synthesis:O,_confidence:{sourcesCount:b.length,fetchedSourceSuccessRate:w.length>0?Number((w.filter((v)=>v.contentChars>100).length/w.length).toFixed(2)):0,agreementLevel:O.agreement?.level||"mixed",floorMet:Q.floorMet}}}function Tr(t){let e=new Map;for(let n of t){let a=n?.id||M(n?.finalUrl||n?.url||"");if(!a)continue;let l=e.get(a);if(!l||(n.contentChars||0)>(l.contentChars||0))e.set(a,n)}let r=[];for(let n of e.values()){let a=String(n.content||n.snippet||""),l=r.findIndex((i)=>{let f=String(i.content||i.snippet||"");if(a.length<400||f.length<400)return!1;return Et(a.slice(0,4000),f.slice(0,4000))>=0.9});if(l===-1){r.push(n);continue}if((n.contentChars||0)>(r[l].contentChars||0))r[l]=n}return r}export{Pr as validateAction,vt as updateQuestionLedger,Er as tokenSet,Cf as runResearchMode,il as queriesToActions,ll as parseActionPlan,Ia as normalizeResearchQueries,Et as jaccardSimilarity,Or as isDuplicateQuery,yl as createQuestionLedger,Cr as computeResearchFloor,Ua as clampResearchOptions,za as buildFallbackQueriesFromGaps,bl as auditCitations};
454
+ `),"utf8"),J(Y(D,"GAPS.md"),["# Gaps and caveats","","## Caveats",Vn(r.caveats||[]),"","## Research gaps",Vn(y),""].join(`
455
+ `),"utf8"),J(Y(P,"manifest.json"),JSON.stringify({...w,floor:l,citationAudit:a},null,2),"utf8"),J(Y(P,"rounds.json"),JSON.stringify(n,null,2),"utf8"),J(Y(P,"sources.json"),JSON.stringify(f,null,2),"utf8"),J(Y(P,"questions.json"),JSON.stringify(_,null,2),"utf8"),J(Y(P,"evidence.json"),JSON.stringify(g,null,2),"utf8"),J(Y(v,"index.md"),["# Source index","",...R.map((j)=>{let I=j.title||j.url,M=j.finalUrl||j.url,A=j.contentPath?` — ${j.contentPath}`:"";return`- ${j.id||"?"}: [${I}](${M})${A}`}),""].join(`
456
+ `),"utf8");try{qa(b,{query:t,rounds:n,sources:f,fetchedSources:p,citationAudit:a,citationUrls:e,floor:l,manifest:w})}catch(j){process.stderr.write(`[greedysearch] Provenance sidecar write failed (non-critical): ${j.message}
457
+ `)}return{dir:b,statusPath:Y(b,"STATUS.md"),summaryPath:Y(D,"SUMMARY.md"),manifestPath:Y(P,"manifest.json"),provenancePath:Y(b,"provenance.md"),sourceCount:R.length,sourceFiles:R}}async function L0({query:t,breadth:n,iterations:f,maxSources:p,locale:g=null,short:r=!1,qualityThreshold:a=8.5,writeBundle:l=process.env.GREEDY_RESEARCH_BUNDLE!=="0",researchOutDir:w=null}={}){let $=ia({breadth:n,iterations:f,maxSources:p}),_=n!==void 0&&n!==null,e=f!==void 0&&f!==null;if(!_&&!e)try{let O=await pf(t);if(process.stderr.write(`[greedysearch] Complexity: ${O.complexity} (${O.reasoning})
458
+ `),O.complexity==="simple")return process.stderr.write(`[greedysearch] Simple query detected using fast single-pass path
459
+ `),Jf({query:t,locale:g,maxSources:Math.min(p??5,5),qualityThreshold:a,writeBundle:l,researchOutDir:w});if(!_)$.breadth=O.suggestedBreadth;if(!e)$.iterations=O.suggestedIterations}catch(O){process.stderr.write(`[greedysearch] Scale classification failed, using defaults: ${O.message}
460
+ `)}let h=[],b=[],D=[],v=Ln(t),P=null,R=[],y=[],j=[],I=new Set,M=new Set,A=new Set,k=[],F="max_rounds",et=new Date().toISOString(),d=Date.now(),wt=0,N=0,o=0,lt=[],Z=ot({totalActions:$.iterations*$.breadth,totalRounds:$.iterations,totalFetches:$.iterations,silent:process.env.GREEDY_RESEARCH_QUIET==="1"});Z.startRound(1),process.stderr.write(`[greedysearch] Research mode: breadth ${$.breadth}, iterations ${$.iterations}, qualityThreshold ${a}, engines ${kt.join(",")}, synthesizer gemini
461
+ `);for(let O=0;O<$.iterations;O++){let L=O+1,s=Math.max(1,Math.ceil($.breadth/2**O));if(process.stderr.write(`PROGRESS:research:round-${L}:planning
462
+ `),!P)try{let C=await X(Ma(t,s,b,D,[...A]),{timeoutMs:120000}),i=ma(C,s);if(O===0)i.unshift({type:"search",query:t,researchGoal:"Original user query"});i=await Va(i,A),P=i}catch(C){process.stderr.write(`[greedysearch] Action planning failed, using fallback queries: ${C.message}
463
+ `);let i=Aa(null,t,s,{includeOriginal:O===0,exclude:M});P=Ja(i)}let Q=(P||[]).filter((C)=>{if(C.type==="search"){let i=!zf(C.query,M,{roundIndex:O,originalQuery:t});if(!i)process.stderr.write(`[greedysearch] Novelty gate rejected search: ${C.query}
464
+ `);return i}if(C.type==="fetchUrl"){let i=!A.has(C.url);if(!i)process.stderr.write(`[greedysearch] Novelty gate rejected fetch: ${C.url}
465
+ `);return i}return!1}).slice(0,s),Bn=ca(R,A);if(!Q.some((C)=>C.type==="fetchUrl")&&Bn.length>0){let C=Bn[0];Q.push({type:"fetchUrl",url:C.url,researchGoal:`Direct fetch of known academic source: ${C.label||C.url}`}),process.stderr.write(`[greedysearch] Forced fetchUrl for academic source: ${C.url}
466
+ `)}let Un=Array(Q.length),sf=Math.min(3,Q.length),uf=0;async function tp(){while(!0){let C=uf++;if(C>=Q.length)return;let i=Q[C];process.stderr.write(`PROGRESS:research:round-${L}:action-${C+1}/${Q.length}
467
+ `),process.stderr.write(`[greedysearch] Action ${C+1}/${Q.length} [${i.type}]: ${(i.query||i.url).slice(0,80)}
468
+ `),Z.startAction(i.type,(i.query||i.url||"").slice(0,60));let W=await Fa(i,{locale:g,short:r,usedQueries:M,usedUrls:A,maxChars:8000});Z.endAction(),Un[C]=W}}await Promise.all(Array.from({length:sf},()=>tp()));let Dt=[];for(let C=0;C<Q.length;C++){let i=Q[C],W=Un[C];if(Dt.push(W),wt++,i.type==="search")N++;if(i.type==="fetchUrl")o++,Z.endFetch(W.ok);if(!W.ok)lt.push({round:L,type:i.type,target:i.query||i.url,error:W.error}),process.stderr.write(`[greedysearch] Action failed: ${W.error}
469
+ `)}let Qn=Dt.filter((C)=>C.action.type==="search"),xn=Dt.filter((C)=>C.action.type==="fetchUrl");Ut(v,{roundNumber:L,actions:Dt}),R=Ba([R,Qn.flatMap((C)=>C.sources||[]),xn.flatMap((C)=>C.sources||[])]);for(let C of xn)if(C.fetchResult)y.push(C.fetchResult);y=xf(y);let zt=Math.max(0,$.maxSources-y.filter((C)=>C?.content||C?.contentChars>100).length);if(zt>0&&R.length>0){process.stderr.write(`PROGRESS:research:round-${L}:fetching
470
+ `);let C=new Set,i=(tt)=>{try{return V(tt||"")}catch{return""}};for(let tt of y)for(let It of[tt?.url,tt?.finalUrl,tt?.canonicalUrl]){let vt=i(It);if(vt)C.add(vt)}let W=R.filter((tt)=>{let It=[tt?.canonicalUrl,tt?.finalUrl,tt?.url].map((vt)=>i(vt)).filter(Boolean);return It.length>0&&It.every((vt)=>!C.has(vt))}),fp=await Na(W,Math.min(zt,W.length),8000,Math.min(3,zt||1));y=xf([...y,...fp]),R=Ft(R,y)}y=Qf(y,R);let np=Dt.map((C)=>({query:C.action.query||C.action.url||"",researchGoal:C.action.researchGoal||""}));process.stderr.write(`PROGRESS:research:round-${L}:evidence
471
+ `),process.stderr.write(`PROGRESS:research:round-${L}:learning
472
+ `);let Yt=await Xa({query:t,questions:v,fetchedSources:y,extractedSourceKeys:I,roundQueries:np,searchSummaries:Qn.map((C)=>({query:C.action.query,researchGoal:C.action.researchGoal,error:C.error||"",engines:Ia(C.result)})),evidenceItems:j}),bt={evidence:Yt.evidence,error:Yt.evidenceError};if(bt.error)process.stderr.write(`[greedysearch] Evidence extraction failed: ${bt.error}
473
+ `);j=[...j,...bt.evidence];for(let C of bt.evidence)Ut(v,{roundNumber:L,learningPayload:{answeredQuestions:C.answers||[],newQuestions:C.newQuestions||[]}});let{learningPayload:Ct,learningError:St}=Yt;if(St)process.stderr.write(`[greedysearch] Learning extraction failed: ${St}
474
+ `);let zn=Array.isArray(Ct.learnings)?Ct.learnings.map((C)=>String(C)).filter(Boolean).slice(0,8):[],ct=Array.isArray(Ct.gaps)?Ct.gaps.map((C)=>String(C)).filter(Boolean).slice(0,6):[];if(b=rt([...b,...zn]),D=rt([...D,...ct]),Ut(v,{roundNumber:L,actions:[],learningPayload:Ct,gaps:ct}),h.push({round:L,actions:Dt.map((C)=>({type:C.action.type,query:C.action.query||"",url:C.action.url||"",researchGoal:C.action.researchGoal||"",error:C.error||"",sourceCount:C.sources?.length||0})),learnings:zn,gaps:ct,evidence:bt.evidence,evidenceError:bt.error,learningError:St}),process.stderr.write(`PROGRESS:research:round-${L}:evaluating
475
+ `),Z.endRound(),L<$.iterations)Z.startRound(L+1);let m=L===$.iterations?{score:k.length>0?k[k.length-1]:5,coverage:{},knowledgeGaps:[],shouldContinue:!1,nextActions:[],terminationReason:null,evaluationError:""}:await Ya(t,h,b,D,k);k.push(m.score),D=rt([...D,...m.knowledgeGaps||[]]),Ut(v,{roundNumber:L,gaps:m.knowledgeGaps||[]});let Sn=Bt({sources:R,fetchedSources:y,gaps:D,questions:v,rounds:h,qualityScore:m.score,qualityThreshold:a,maxSources:$.maxSources,requireCitations:!1,requireQuestions:!1});if(process.stderr.write(`[greedysearch] Quality score round ${L}: ${m.score.toFixed(1)} (shouldContinue: ${m.shouldContinue}, floor: ${Sn.floorMet})
476
+ `),m.score>=a&&Sn.floorMet&&(!m.shouldContinue||m.terminationReason==="quality_threshold")){F=m.terminationReason||"quality_threshold",process.stderr.write(`[greedysearch] Research floor reached (score: ${m.score.toFixed(1)}). Terminating early.
477
+ `);break}let _t=Math.max(1,Math.ceil(s/2)),u=(Ct.followUpQueries||[]).map((C)=>({type:"search",query:c(String(C)),researchGoal:"Follow-up from learning extraction"})).filter((C)=>C.query&&C.query.toLowerCase()!==t.toLowerCase()).slice(0,_t);if(u.length<_t&&m.nextActions.length>0){let C=m.nextActions.map((W)=>Sf(W)).filter(Boolean);u=[...u,...C].slice(0,_t)}if(u.length<_t&&D.length>0){let C=La(D,t,M,_t-u.length,O+1),i=C.map((W)=>({type:"search",query:W.query,researchGoal:W.researchGoal}));if(u=[...u,...i].slice(0,_t),C.length>0)process.stderr.write(`[greedysearch] Generated ${C.length} gap-driven fallback actions.
478
+ `)}P=u.length>=_t?u:null}process.stderr.write(`PROGRESS:research:final-report
479
+ `);let T={answer:b.length?b.map((O)=>`- ${O}`).join(`
480
+ `):"Research completed, but no structured learnings were extracted.",agreement:{level:"mixed",summary:"Research synthesis fallback."},differences:[],caveats:[],claims:[],recommendedSources:R.slice(0,4).map((O)=>O.id),synthesized:!1};try{let O=await X(An(t,h,R,v,j),{timeoutMs:180000}),L=Ht(O,{}),s=Array.isArray(L?.claims)&&L.claims.length>0;T={...T,...L,rawAnswer:O.answer||"",geminiSources:O.sources||[],synthesized:s}}catch(O){process.stderr.write(`[greedysearch] Final report failed: ${O.message}
481
+ `),T.error=O.message}if(!(T.synthesized===!0&&Array.isArray(T.claims)&&T.claims.length>0)&&j.length>0){process.stderr.write(`[greedysearch] Falling back to evidence-based synthesis (no per-round learnings).
482
+ `);try{let O=Tn(t,R,v,j),L=await X(O,{timeoutMs:180000}),s=Ht(L,{});T={...T,...s,rawAnswer:L.answer||T.answer||"",geminiSources:L.sources||T.geminiSources||[],synthesized:!0,synthesisMode:"evidence_fallback"}}catch(O){process.stderr.write(`[greedysearch] Evidence-based synthesis failed: ${O.message}
483
+ `),T.evidenceFallbackError=O.message}}let q=new Date().toISOString(),xt=Date.now()-d,qf=k.at(-1)||0;y=Qf(y,R),process.stderr.write(`PROGRESS:research:audit-citations
484
+ `);let Ot=kn(T.answer||"",R),Xn=await Hn(R,Ot);Yn(v,T,Ot);let Et=Bt({sources:R,fetchedSources:y,synthesis:T,citationAudit:Ot,gaps:D,questions:v,rounds:h,qualityScore:qf,qualityThreshold:a,maxSources:$.maxSources});if(Et.floorMet&&F==="max_rounds")F="done_floor_met";else if(!Et.floorMet&&F==="quality_threshold")F="max_rounds_floor_unmet";let on={startedAt:et,finishedAt:q,durationMs:xt,engines:kt,synthesizer:"gemini",rounds:h.length,actionsRun:wt,searches:N,fetches:o,sourcesFetched:y.filter((O)=>O?.contentChars>100).length,engineFailures:lt,terminationReason:F,floorMet:Et.floorMet},Nt=null,Lt;if(l){process.stderr.write(`PROGRESS:research:bundle
485
+ `);try{Nt=await In({query:t,rounds:h,sources:R,fetchedSources:y,evidenceItems:j,synthesis:T,citationAudit:Ot,citationUrls:Xn,floor:Et,manifest:on,allGaps:D,questions:v,outDir:w}),Lt=Nt.sourceFiles,delete Nt.sourceFiles}catch(O){Nt={error:O.message||String(O)},Lt=await mn(y)}}else Lt=await mn(y);return process.stderr.write(`PROGRESS:research:done
486
+ `),Z.finish(),{query:t,_research:{mode:"iterative",breadth:$.breadth,iterations:$.iterations,maxSources:$.maxSources,rounds:h,learnings:b,gaps:D,evidence:j,questions:v,questionProgress:Zn(v),qualityHistory:k,terminationReason:F,qualityThreshold:a,floor:Et,bundle:Nt,manifest:on},_citationAudit:Ot,_citationUrls:Xn,_sources:R,_fetchedSources:Lt,_synthesis:T,_confidence:{sourcesCount:R.length,fetchedSourceSuccessRate:y.length>0?Number((y.filter((O)=>O.contentChars>100).length/y.length).toFixed(2)):0,agreementLevel:T.agreement?.level||"mixed",floorMet:Et.floorMet}}}function xf(t){let n=new Map;for(let a of t){let l=a?.id||V(a?.finalUrl||a?.url||"");if(!l)continue;let w=n.get(l);if(!w||(a.contentChars||0)>(w.contentChars||0))n.set(l,a)}let f=new Map;function p(a){let l=f.get(a);if(!l){let w=String(a.content||a.snippet||"");l={length:w.length,tokens:Jn(w.slice(0,4000))},f.set(a,l)}return l}function g(a,l){let w=0,$=a.size<=l.size?a:l,_=a.size<=l.size?l:a;for(let E of $)if(_.has(E))w++;let e=a.size+l.size-w;if(e===0)return 1;return w/e}let r=[];for(let a of n.values()){let l=p(a),w=r.findIndex(($)=>{let _=f.get($);if(l.length<400||_.length<400)return!1;return g(l.tokens,_.tokens)>=0.9});if(w===-1){r.push(a);continue}if((a.contentChars||0)>(r[w].contentChars||0))r[w]=a}return r}export{In as writeResearchBundle,qa as writeProvenanceSidecar,Sf as validateAction,Ut as updateQuestionLedger,Jn as tokenSet,L0 as runResearchMode,Hn as runCitationUrlCheck,Yn as reconcileQuestionsFromSynthesis,Ja as queriesToActions,ma as parseActionPlan,Aa as normalizeResearchQueries,Kn as jaccardSimilarity,zf as isDuplicateQuery,Zf as extractEvidenceFromSources,Xa as extractEvidenceAndLearnings,Ln as createQuestionLedger,Bt as computeResearchFloor,ia as clampResearchOptions,za as checkCitationUrls,Tn as buildSynthesisFromEvidencePrompt,An as buildFinalReportPrompt,La as buildFallbackQueriesFromGaps,Ka as buildEvidenceAndLearningPrompt,kn as auditCitations};