@duckmind/dm-windows-x64 0.59.3 → 0.60.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dm.exe +0 -0
- package/extensions/.dm-extensions.json +11 -7
- package/extensions/dm-cliproxy/index.js +1 -1
- package/extensions/dm-cliproxy/src/apply.js +1 -1
- package/extensions/dm-cliproxy/src/commands.js +1 -1
- package/extensions/dm-cliproxy/src/fetch-models.js +1 -1
- package/extensions/dm-cliproxy/src/ui-hub/hub.js +1 -1
- package/extensions/dm-cliproxy/src/ui-hub/index.js +1 -1
- package/extensions/dm-cua/bin/browser-cua.mjs +4 -4
- package/extensions/dm-cua/index.js +3 -3
- package/extensions/dm-cua/src/browser-cua-lib.mjs +3 -3
- package/extensions/greedysearch-dm/bin/mcp.mjs +52 -52
- package/extensions/greedysearch-dm/bin/search.mjs +130 -131
- package/extensions/greedysearch-dm/extractors/consensus.mjs +42 -43
- package/extensions/greedysearch-dm/extractors/gemini.mjs +52 -53
- package/extensions/greedysearch-dm/extractors/logically.mjs +33 -34
- package/extensions/greedysearch-dm/src/search/browser-lifecycle.mjs +9 -10
- package/extensions/greedysearch-dm/src/search/chrome.mjs +21 -22
- package/extensions/greedysearch-dm/src/search/engines.mjs +7 -7
- package/extensions/greedysearch-dm/src/search/fetch-source.mjs +48 -48
- package/extensions/greedysearch-dm/src/search/paths.mjs +1 -1
- package/extensions/greedysearch-dm/src/search/research.mjs +119 -119
- package/extensions/greedysearch-dm/src/search/scale-aware.mjs +7 -7
- package/extensions/greedysearch-dm/src/search/simple-research.mjs +125 -125
- package/extensions/greedysearch-dm/src/search/synthesis-runner.mjs +11 -11
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{createRequire as
|
|
1
|
+
import{createRequire as lp}from"node:module";var pp=Object.defineProperty;var ap=(t)=>t;function gp(t,n){this[t]=ap.bind(null,n)}var dt=(t,n)=>{for(var f in n)pp(t,f,{get:n[f],enumerable:!0,configurable:!0,set:gp.bind(n,f)})};var qt=(t,n)=>()=>(t&&(n=t(t=0)),n);var Ft=lp(import.meta.url);var gf={};dt(gf,{writeSourcesToFiles:()=>mt});import{mkdirSync as Wp,writeFileSync as mp}from"node:fs";import{join as af}from"node:path";function mt(t,n=Vp){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,""),a=(f.canonicalUrl||f.url||"").replace(/^https?:\/\//,"").replace(/[^a-zA-Z0-9]/g,"-").slice(0,40),l=`${p}-${a}.md`,g=af(n,l),r=`---
|
|
2
2
|
url: ${f.finalUrl||f.url}
|
|
3
3
|
title: ${f.title||""}
|
|
4
4
|
source: ${f.source||"unknown"}
|
|
@@ -6,27 +6,27 @@ status: ${f.status||""}
|
|
|
6
6
|
chars: ${f.contentChars||f.content.length}
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
`;
|
|
9
|
+
`;mp(g,r+f.content,"utf8");let{content:w,...$}=f;return{...$,contentPath:g,contentChars:f.contentChars||w.length}})}var Vp;var gn=qt(()=>{Vp=af(process.cwd(),".dm","greedysearch-sources")});var Nn={};dt(Nn,{fetchTopSource:()=>ua,fetchSourceContent:()=>Wf,fetchMultipleSources:()=>On});import{createRequire as Jp}from"node:module";import{createRequire as Zp}from"node:module";import{spawn as ra}from"node:child_process";import{basename as wa}from"node:path";import{dirname as $a,join as _a}from"node:path";import{fileURLToPath as ea}from"node:url";import{fileURLToPath as ha}from"node:url";import{existsSync as Jt,mkdirSync as Ea,readFileSync as Tf,writeFileSync as Da}from"node:fs";import{homedir as ba}from"node:os";import{join as Af}from"node:path";import{tmpdir as Ca}from"node:os";import{existsSync as Zt,mkdirSync as va,readFileSync as kf,writeFileSync as ja}from"node:fs";import{homedir as Pa}from"node:os";import{join as Hf}from"node:path";import{tmpdir as Ra}from"node:os";import{existsSync as Kt,mkdirSync as Ja,readFileSync as If,writeFileSync as Za}from"node:fs";import{homedir as Ka}from"node:os";import{join as Ff}from"node:path";import{tmpdir as Xa}from"node:os";async function Kp(){if(Vt)return Vt;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:(a)=>a.tagName==="IMG"&&a.getAttribute("src")?.startsWith("data:"),replacement:()=>""}),Vt={Readability:t,JSDOM:n,turndown:p},Vt}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((a)=>Bp.test(a)))return null;let f=n.map((a)=>{if(/^0x/i.test(a))return parseInt(a,16);if(/^0[0-7]+$/.test(a))return parseInt(a,8);return parseInt(a,10)});if(f.some((a)=>!Number.isFinite(a)||a<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((a)=>a>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),a=parseInt(f[2],16);if(p>65535||a>65535)return null;return[p>>>8&255,p&255,a>>>8&255,a&255].join(".")}return null}function lf(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 a of jf)if(a.test(f))return{blocked:!0,reason:`Private/internal address: ${f}`};if(f.startsWith("[")&&f.endsWith("]")){let a=f.slice(1,-1),l=Qp(a);if(l&&lf(l))return{blocked:!0,reason:`Private/internal address: ${f} (maps to ${l})`}}let p=Up(f);if(p&&lf(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,a,l,g,...r]=f;if(l!=="blob")return t;let w=r.join("/");return`https://raw.githubusercontent.com/${p}/${a}/${g}/${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:a=15000,userAgent:l,signal:g}=n,r=new AbortController,w=setTimeout(()=>r.abort(),a);if(g)g.addEventListener("abort",()=>r.abort(),{once:!0});try{let $=await fetch(t,{method:"GET",headers:{...vf,"user-agent":l||Cf},redirect:"follow",signal:r.signal});clearTimeout(w);let _=$.headers.get("content-type")||"",h=$.url,E=$.headers.get("last-modified")||"",e=$n(h);if(e.blocked)return{ok:!1,url:t,finalUrl:h,status:$.status,error:`Blocked: ${e.reason}`,needsBrowser:!1};let b=!1;try{b=new URL(h).hostname.toLowerCase()==="raw.githubusercontent.com"}catch{}if(_.includes("text/plain")&&b){let y=await $.text();return{ok:!0,url:p,finalUrl:h,status:$.status,title:h.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:h,status:$.status,error:`Unsupported content type: ${_}`,needsBrowser:!1};let D=await $.text(),v=Pf($.status,D,h,t);if(v.blocked)return{ok:!1,url:t,finalUrl:h,status:$.status,error:`Blocked: ${v.reason}`,needsBrowser:!0};let P=await Rf(D,h),R=yf(P);if(!R.ok)return{ok:!1,url:t,finalUrl:h,status:$.status,error:`Low quality content: ${R.reason}`,needsBrowser:!0};return{ok:!0,url:t,finalUrl:h,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 a=n.match(/<title[^>]*>([^<]*)<\/title>/i)?.[1]?.toLowerCase()||"",l=n.slice(0,30000).toLowerCase(),g=`${a} ${l}`;if(t===403||t===429||t===503)return{blocked:!0,reason:`HTTP ${t}`};let r=[{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 r)if($.pattern.test(g))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),a=new URL(n);if(p.hostname.toLowerCase()===a.hostname.toLowerCase())return;let l=a.hostname.toLowerCase();if(cp.some((r)=>l===r||l.endsWith(`.${r}`)))return`redirected to login (${a.hostname})`;if(dp.some((r)=>l.startsWith(r)))return`redirected to login (${a.hostname})`;let g=f.slice(0,20000).toLowerCase();if(qp.some((r)=>g.includes(r)))return`redirected to login page (${a.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 rf(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),a=p?.getAttribute("content")||p?.getAttribute("datetime")||"";if(a)return a}return""}async function Rf(t,n){let{Readability:f,JSDOM:p,turndown:a}=await Kp(),l=new p(t,{url:n});try{let g=l.window.document,r=new f(g).parse();if(r&&r.content){let $=a.turndown(r.content).replaceAll(/\n{3,}/g,`
|
|
10
10
|
|
|
11
|
-
`).trim(),_=
|
|
11
|
+
`).trim(),_=r.publishedTime||rf(g)||"";return{title:r.title||g.title||n,byline:r.byline||"",siteName:r.siteName||"",lang:r.lang||"",publishedTime:_,markdown:$,excerpt:$.slice(0,300).replaceAll(/\n/g," ")}}let w=g.body;if(w){let $=w.cloneNode(!0);$.querySelectorAll("script, style, nav, footer, header, aside").forEach((h)=>h.remove());let _=($.textContent||"").replaceAll(/\s+/g," ").trim();return{title:g.title||n,byline:"",siteName:"",lang:"",publishedTime:rf(g),markdown:_,excerpt:_.slice(0,300)}}return{title:n,byline:"",siteName:"",lang:"",publishedTime:"",markdown:"",excerpt:""}}finally{l.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(),a=[{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:l,desc:g}of a)if(l())return{ok:!1,reason:g};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,a]=f;if(f.length===2)return{owner:p,repo:a,type:"root"};if(f.length>=4&&(f[2]==="blob"||f[2]==="tree")){let l=f[2],g=f[3],r=f.slice(4).join("/");return{owner:p,repo:a,type:l,ref:g,path:r}}return null}catch{return null}}async function B(t,n=1e4){let f=new AbortController,p=setTimeout(()=>f.abort(),n);try{let a=await fetch(`https://api.github.com${t}`,{headers:Of,signal:f.signal});if(clearTimeout(p),!a.ok)throw Error(`GitHub API ${a.status}: ${t}`);return await a.json()}catch(a){throw clearTimeout(p),a}}async function ta(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="",a){try{let l;if(f==="HEAD")if(a)l=await B(`/repos/${t}/${n}/git/ref/heads/${a}`).catch(()=>null);else l=await Promise.any([B(`/repos/${t}/${n}/git/ref/heads/main`),B(`/repos/${t}/${n}/git/ref/heads/master`)]).catch(()=>null);else l=await B(`/repos/${t}/${n}/git/ref/heads/${f}`).catch(()=>B(`/repos/${t}/${n}/git/ref/heads/master`).catch(()=>null));if(!l?.object?.sha)return[];let g=(await B(`/repos/${t}/${n}/git/commits/${l.object.sha}`)).tree.sha,r=(await B(`/repos/${t}/${n}/git/trees/${g}`)).tree||[];if(p)r=r.filter((w)=>w.path.startsWith(p));return r.slice(0,50).map((w)=>({path:w.path,type:w.type==="tree"?"dir":"file",size:w.size}))}catch{return[]}}async function na(t,n,f,p,a=1e4,l){let g=async(w)=>{let $=new AbortController,_=setTimeout(()=>$.abort(),a);try{let h=await fetch(w,{headers:{"user-agent":Of["user-agent"]},signal:$.signal});if(clearTimeout(_),h.ok)return await h.text();throw Error("not ok")}catch{throw clearTimeout(_),Error("failed")}};if(!f||f==="HEAD"){if(l)try{return await g(`https://raw.githubusercontent.com/${t}/${n}/${l}/${p}`)}catch{return null}try{return await Promise.any([g(`https://raw.githubusercontent.com/${t}/${n}/main/${p}`),g(`https://raw.githubusercontent.com/${t}/${n}/master/${p}`)])}catch{return null}}let r=[`https://raw.githubusercontent.com/${t}/${n}/${f}/${p}`,`https://raw.githubusercontent.com/${t}/${n}/master/${p}`];for(let w of r)try{return await g(w)}catch{}return null}async function fa(t){let n=_n(t);if(!n)return{ok:!1,error:"Not a valid GitHub URL"};let{owner:f,repo:p,type:a,ref:l,path:g}=n;try{if(a==="root"||a==="tree"&&!g){let r=await B(`/repos/${f}/${p}`),[w,$]=await Promise.allSettled([ta(f,p),wf(f,p,l||"HEAD","",r.default_branch)]),_=w.status==="fulfilled"?w.value:"",h=$.status==="fulfilled"?$.value:[],E=r?.description?`
|
|
12
12
|
|
|
13
|
-
> ${
|
|
13
|
+
> ${r.description}`:"",e=r?.stargazers_count==null?"":` ⭐ ${r.stargazers_count}`,b=r?.language?` · ${r.language}`:"",D=`# ${f}/${p}${e}${b}${E}
|
|
14
14
|
|
|
15
15
|
`;if(_)D+=_.slice(0,6000);else D+=`[No README found]
|
|
16
16
|
|
|
17
17
|
Files:
|
|
18
|
-
${
|
|
19
|
-
`)}`;return{ok:!0,title:`${f}/${p}`,content:D,tree:
|
|
20
|
-
`);return{ok:!0,title:`${f}/${p}/${
|
|
18
|
+
${h.map((v)=>` ${v.type==="dir"?"\uD83D\uDCC1":"\uD83D\uDCC4"} ${v.path}`).join(`
|
|
19
|
+
`)}`;return{ok:!0,title:`${f}/${p}`,content:D,tree:h.slice(0,30)}}if(a==="blob"&&g){let r;if(!l||l==="HEAD")try{r=(await B(`/repos/${f}/${p}`)).default_branch}catch{r=void 0}let w=await na(f,p,l,g,1e4,r);if(w===null)return{ok:!1,error:`File not found: ${g}`};return{ok:!0,title:`${f}/${p}: ${g}`,content:w}}if(a==="tree"&&g){let r;if(!l||l==="HEAD")try{r=(await B(`/repos/${f}/${p}`)).default_branch}catch{r=void 0}let w=await wf(f,p,l||"HEAD",g,r),$=w.map((_)=>` ${_.type==="dir"?"\uD83D\uDCC1":"\uD83D\uDCC4"} ${_.path}`).join(`
|
|
20
|
+
`);return{ok:!0,title:`${f}/${p}/${g}`,content:`[Directory: ${g}]
|
|
21
21
|
|
|
22
22
|
Files:
|
|
23
|
-
${$}`,tree:w}}return{ok:!1,error:"Unsupported GitHub URL type"}}catch(
|
|
23
|
+
${$}`,tree:w}}return{ok:!1,error:"Unsupported GitHub URL type"}}catch(r){return{ok:!1,error:r.message}}}function aa(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 ga(t,n=8000){let f=Date.now();try{let p=t.replace(/\/+$/,"")+".json",a=new AbortController,l=setTimeout(()=>a.abort(),15000),g=await fetch(p,{headers:pa,signal:a.signal});if(clearTimeout(l),!g.ok)throw Error(`Reddit API ${g.status}`);let r=await g.json();if(!Array.isArray(r)||r.length<1)throw Error("Invalid Reddit API response structure");let w=r[0],$=r[1],_=w?.data?.children?.[0]?.data;if(!_)throw Error("No post data in Reddit response");let h=la(_,$,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:h,contentLength:h.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 la(t,n,f){let p="";if(p+=`# ${t.title}
|
|
24
24
|
|
|
25
25
|
`,p+=`**Subreddit:** r/${t.subreddit} | **Author:** u/${t.author} | **Score:** ${t.score}
|
|
26
26
|
|
|
27
27
|
`,t.selftext)p+=t.selftext,p+=`
|
|
28
28
|
|
|
29
|
-
`;else if(t.url)try{let
|
|
29
|
+
`;else if(t.url)try{let a=new URL(t.url).hostname.toLowerCase();if(a!=="reddit.com"&&!a.endsWith(".reddit.com"))p+=`**Link:** ${t.url}
|
|
30
30
|
|
|
31
31
|
`}catch{p+=`**Link:** ${t.url}
|
|
32
32
|
|
|
@@ -34,21 +34,21 @@ ${$}`,tree:w}}return{ok:!1,error:"Unsupported GitHub URL type"}}catch(l){return{
|
|
|
34
34
|
|
|
35
35
|
## Comments
|
|
36
36
|
|
|
37
|
-
`;let
|
|
37
|
+
`;let a=n.data.children.filter((l)=>l.kind==="t1").slice(0,10);for(let l of a)p+=Nf(l.data,0),p+=`
|
|
38
38
|
`}if(p.length>f)p=p.slice(0,f).trim()+`
|
|
39
39
|
|
|
40
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
41
|
`,p+=`${f}${t.body.replaceAll(`
|
|
42
42
|
`,`
|
|
43
43
|
`+f)}
|
|
44
|
-
`,n<3&&t.replies?.data?.children){let
|
|
45
|
-
`+Nf(
|
|
44
|
+
`,n<3&&t.replies?.data?.children){let a=t.replies.data.children.filter((l)=>l.kind==="t1");for(let l of a.slice(0,5))p+=`
|
|
45
|
+
`+Nf(l.data,n+1)}return p}function Rt(t,n=8000){if(!t||t.length<=n)return t;let f=`
|
|
46
46
|
|
|
47
47
|
[...content trimmed...]
|
|
48
48
|
|
|
49
|
-
`,p=n-f.length,
|
|
50
|
-
`)
|
|
51
|
-
`)
|
|
49
|
+
`,p=n-f.length,a=Math.floor(p*0.75),l=p-a,g=a;while(g>a-100&&t[g]!==`
|
|
50
|
+
`)g--;if(g<=a-100)g=a;let r=t.length-l;while(r<t.length-l+100&&t[r]!==`
|
|
51
|
+
`)r++;if(r>=t.length-l+100)r=t.length-l;let w=t.slice(0,g).trimEnd(),$=t.slice(r).trimStart();return`${w}${f}${$}`}function ya(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=wa(n||"").toLowerCase();if(p==="node"||p==="node.exe")return n;return"node"}function Ta(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(!ia.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 Aa(t,null,n)}function Aa(t,n=null,f=30000){let p=Ta(t);return new Promise((a,l)=>{let g=ra(ya(),[Na,...p],{stdio:[n==null?"ignore":"pipe","pipe","pipe"]});if(n!=null)g.stdin.write(n),g.stdin.end();let r="",w="";g.stdout.on("data",(_)=>r+=_),g.stderr.on("data",(_)=>w+=_);let $=setTimeout(()=>{g.kill(),l(Error(`cdp timeout: ${t[0]}`))},f);g.on("close",(_)=>{if(clearTimeout($),_===0)a(r.trim());else l(Error(w.trim()||`cdp exit ${_}`))})})}async function ef(t){await Lf(["evalraw",t,"Page.addScriptToEvaluateOnNewDocument",JSON.stringify({source:`
|
|
52
52
|
(function() {
|
|
53
53
|
// ── Runtime.enable / CDP detection masking ──────────────
|
|
54
54
|
try { delete window.__REBROWSER_RUNTIME_ENABLE; } catch(_) {}
|
|
@@ -333,35 +333,35 @@ ${$}`,tree:w}}return{ok:!1,error:"Unsupported GitHub URL type"}}catch(l){return{
|
|
|
333
333
|
};
|
|
334
334
|
} catch(_) {}
|
|
335
335
|
})();
|
|
336
|
-
`})])}function
|
|
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(", ")}
|
|
336
|
+
`})])}function ka(t){return ha(new URL(".",t)).replace(/^\/([A-Z]:)/,"$1")}function Ha(t,n=9222){let f=Number.parseInt(String(t??""),10);return Number.isInteger(f)&&f>1024&&f<65535?f:n}function Ya(){try{if(Jt(pt)){let t=Tf(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((a)=>ln[a]),p=n.engines.filter((a)=>!ln[a]);if(p.length>0)process.stderr.write(`[greedysearch] Warning: ignoring unknown engine(s) in ${pt}: ${p.join(", ")}
|
|
344
337
|
[greedysearch] Available engines: ${Object.keys(ln).join(", ")}
|
|
345
|
-
`);if(f.length>0)return f;process.stderr.write(`[greedysearch] Warning: no valid engines in ${
|
|
346
|
-
`)}}}catch{}return
|
|
347
|
-
`,"utf8")}catch{}}function
|
|
338
|
+
`);if(f.length>0)return f;process.stderr.write(`[greedysearch] Warning: no valid engines in ${pt}, falling back to defaults: ${hn.join(", ")}
|
|
339
|
+
`)}}}catch{}return hn}function Ia(){try{if(!Jt(en))Ea(en,{recursive:!0});if(!Jt(pt))Da(pt,JSON.stringify({engines:hn,synthesizer:En},null,2)+`
|
|
340
|
+
`,"utf8")}catch{}}function Fa(){try{if(Jt(pt)){let t=Tf(pt,"utf8"),n=JSON.parse(t);if(typeof n.synthesizer==="string"){let f=n.synthesizer.toLowerCase();if(hf.includes(f))return f;process.stderr.write(`[greedysearch] Warning: unknown synthesizer "${n.synthesizer}" in ${pt}
|
|
341
|
+
[greedysearch] Available synthesizers: ${hf.join(", ")}
|
|
342
|
+
[greedysearch] Falling back to default: ${En}
|
|
343
|
+
`)}}}catch{}return En}function Ga(t,n=9222){let f=Number.parseInt(String(t??""),10);return Number.isInteger(f)&&f>1024&&f<65535?f:n}function Wa(){try{if(Zt(at)){let t=kf(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((a)=>rn[a]),p=n.engines.filter((a)=>!rn[a]);if(p.length>0)process.stderr.write(`[greedysearch] Warning: ignoring unknown engine(s) in ${at}: ${p.join(", ")}
|
|
344
|
+
[greedysearch] Available engines: ${Object.keys(rn).join(", ")}
|
|
345
|
+
`);if(f.length>0)return f;process.stderr.write(`[greedysearch] Warning: no valid engines in ${at}, falling back to defaults: ${bn.join(", ")}
|
|
346
|
+
`)}}}catch{}return bn}function ma(){try{if(!Zt(Dn))va(Dn,{recursive:!0});if(!Zt(at))ja(at,JSON.stringify({engines:bn,synthesizer:Cn},null,2)+`
|
|
347
|
+
`,"utf8")}catch{}}function Va(){try{if(Zt(at)){let t=kf(at,"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 ${at}
|
|
348
348
|
[greedysearch] Available synthesizers: ${Ef.join(", ")}
|
|
349
349
|
[greedysearch] Falling back to default: ${Cn}
|
|
350
|
-
`)}}}catch{}return Cn}async function Yf(){let t=(await
|
|
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
|
|
350
|
+
`)}}}catch{}return Cn}async function Yf(){let t=(await M(["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 l=await M(["evalraw",n,"Target.createTarget",JSON.stringify({url:"about:blank"})]),{targetId:g}=JSON.parse(l),r=g.slice(0,8);if(await M(["list"]).catch(()=>null),f==="copilot.microsoft.com")await ef(r);else ef(r).catch(()=>{});return await M(["list"]).catch(()=>null),g}let p=await M(["evalraw",n,"Target.createTarget",JSON.stringify({url:t})]),{targetId:a}=JSON.parse(p);return await M(["list"]).catch(()=>null),a}async function yn(t){try{let n=await Yf();await M(["evalraw",n,"Target.closeTarget",JSON.stringify({targetId:t})])}catch{}}function oa(t,n=9222){let f=Number.parseInt(String(t??""),10);return Number.isInteger(f)&&f>1024&&f<65535?f:n}function Ua(){try{if(Kt(gt)){let t=If(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((a)=>wn[a]),p=n.engines.filter((a)=>!wn[a]);if(p.length>0)process.stderr.write(`[greedysearch] Warning: ignoring unknown engine(s) in ${gt}: ${p.join(", ")}
|
|
352
352
|
[greedysearch] Available engines: ${Object.keys(wn).join(", ")}
|
|
353
|
-
`);if(f.length>0)return f;process.stderr.write(`[greedysearch] Warning: no valid engines in ${
|
|
354
|
-
`)}}}catch{}return jn}function
|
|
355
|
-
`,"utf8")}catch{}}function
|
|
353
|
+
`);if(f.length>0)return f;process.stderr.write(`[greedysearch] Warning: no valid engines in ${gt}, falling back to defaults: ${jn.join(", ")}
|
|
354
|
+
`)}}}catch{}return jn}function Qa(){try{if(!Kt(vn))Ja(vn,{recursive:!0});if(!Kt(gt))Za(gt,JSON.stringify({engines:jn,synthesizer:Pn},null,2)+`
|
|
355
|
+
`,"utf8")}catch{}}function xa(){try{if(Kt(gt)){let t=If(gt,"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 ${gt}
|
|
356
356
|
[greedysearch] Available synthesizers: ${Df.join(", ")}
|
|
357
357
|
[greedysearch] Falling back to default: ${Pn}
|
|
358
|
-
`)}}}catch{}return Pn}function
|
|
358
|
+
`)}}}catch{}return Pn}function za(){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 Sa(){za();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 ca(t,n){try{let f=new(await Sa())({data:new Uint8Array(t)});await f.load();let p=await f.getText(),a=p.text?.trim();if(!a)return null;return{title:new URL(n).pathname.split("/").pop()||"Document.pdf",content:`## PDF Content (${p.total} pages)
|
|
359
359
|
|
|
360
|
-
${
|
|
361
|
-
`)}}if(
|
|
362
|
-
`);let
|
|
363
|
-
`)}let p=await Sp(t,{timeoutMs:1e4});if(p.ok){let
|
|
364
|
-
`),await
|
|
360
|
+
${a}`,pages:p.total}}catch(f){return{error:f.message||String(f)}}}function Gf(t="",n=240){let f=String(t).replaceAll(/\s+/g," ").trim();if(f.length<=n)return f;let p=f.slice(0,n),a=p.lastIndexOf(" ");return a>0?`${p.slice(0,a)}...`:`${p}...`}async function da(t,n,f=8000){let p=Date.now();try{let a=(await M(["evalraw",t,"Page.getFrameTree","{}"]).then((E)=>JSON.parse(E)).catch(()=>null))?.frameTree?.frame?.id||void 0,l=await M(["evalraw",t,"Network.loadNetworkResource",JSON.stringify({frameId:a,url:n,options:{disableCache:!0,includeCredentials:!1}})],20000),g=JSON.parse(l).resource;if(!g?.success||!g.httpStatusCode)return{url:n,error:g?.netErrorName||g?.netError||"loadNetworkResource failed",source:"chrome",duration:Date.now()-p,needsFallback:!0};let r="";if(g.stream)try{let E=await M(["evalraw",t,"IO.read",JSON.stringify({handle:g.stream})],1e4);r=JSON.parse(E).data||"",await M(["evalraw",t,"IO.close",JSON.stringify({handle:g.stream})]).catch(()=>{})}catch{}if(!r||r.length<100)return{url:n,error:"Empty response body from Network.loadNetworkResource",source:"chrome",duration:Date.now()-p,needsFallback:!0};let w=Pf(g.httpStatusCode,r,n,n);if(w.blocked)return{url:n,status:g.httpStatusCode,error:`Blocked: ${w.reason}`,source:"chrome",duration:Date.now()-p,needsBrowser:!0};let $=await Rf(r,n),_=yf($);if(!_.ok)return{url:n,status:g.httpStatusCode,error:`Low quality: ${_.reason}`,source:"chrome",duration:Date.now()-p,needsBrowser:!0};let h=Rt($.markdown,f);return{url:n,finalUrl:n,status:g.httpStatusCode,contentType:"text/markdown",lastModified:"",publishedTime:$.publishedTime||"",byline:$.byline||"",siteName:$.siteName||"",lang:$.lang||"",title:$.title||n,snippet:$.excerpt,content:h,contentChars:h.length,source:"chrome",duration:Date.now()-p}}catch(a){return{url:n,error:a.message,source:"chrome",duration:Date.now()-p,needsFallback:!0}}}function Mf(t){try{return new URL(t).pathname.toLowerCase().endsWith(".pdf")}catch{return!1}}async function qa(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,a=setTimeout(()=>p.abort(),20000),l=Date.now();try{let g=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(a);let r=g.headers.get("content-type")||"",w=g.url||t,$=Number.parseInt(g.headers.get("content-length")||"0",10);if(g.status>=400)return{url:t,finalUrl:w,status:g.status,error:`HTTP ${g.status}`,source:"pdf-http",duration:Date.now()-l};if(!r.toLowerCase().includes("application/pdf")&&!Mf(w))return null;if($>31457280)return{url:t,finalUrl:w,status:g.status,error:`PDF too large: ${$} bytes`,source:"pdf-http",duration:Date.now()-l};let _=Buffer.from(await g.arrayBuffer()),h=await ca(_,w);if(!h||h.error)return{url:t,finalUrl:w,status:g.status,error:h?.error||"PDF text extraction failed",source:"pdf-http",duration:Date.now()-l};let E=Rt(h.content,n);return{url:t,finalUrl:w,status:g.status,contentType:"application/pdf",lastModified:g.headers.get("last-modified")||"",title:h.title,snippet:Gf(E,320),content:E,contentChars:E.length,pages:h.pages,source:"pdf-http",duration:Date.now()-l}}catch(g){return clearTimeout(a),{url:t,finalUrl:t,error:g.message||String(g),source:"pdf-http",duration:Date.now()-l}}}async function Wf(t,n=8000){let f=Date.now();if(Mf(t)){let a=await qa(t,n);if(a?.content||a?.status===403)return a}if(_n(t)){let a=_n(t);if(a&&(a.type==="root"||a.type==="tree"||a.type==="blob"&&!a.path?.includes("."))){let l=await fa(t);if(l.ok){let g=Rt(l.content,n);return{url:t,finalUrl:t,status:200,contentType:"text/markdown",lastModified:"",title:l.title,snippet:g.slice(0,320),content:g,contentChars:g.length,source:"github-api",...l.tree&&{tree:l.tree},duration:Date.now()-f}}process.stderr.write(`[greedysearch] GitHub API fetch failed, trying HTTP: ${l.error}
|
|
361
|
+
`)}}if(aa(t)?.type==="post"){process.stderr.write(`[greedysearch] Using Reddit JSON API for: ${t.slice(0,60)}...
|
|
362
|
+
`);let a=await ga(t,n);if(a.ok){let l=Rt(a.markdown,n);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()-f}}process.stderr.write(`[greedysearch] Reddit API fetch failed, falling back to HTTP: ${a.error}
|
|
363
|
+
`)}let p=await Sp(t,{timeoutMs:1e4});if(p.ok){let a=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:a,contentChars:a.length,source:"http",duration:Date.now()-f}}if(p.needsBrowser)try{let a=await Rn();try{let l=await da(a,t,n);if(l.content&&l.content.length>100)return l}finally{await yn(a)}}catch{}return process.stderr.write(`[greedysearch] HTTP failed for ${t.slice(0,60)}, trying browser...
|
|
364
|
+
`),await sa(t,n)}async function mf(t,n=4000,f=200){let p=Date.now()+n;while(Date.now()<p){try{if((await M(["eval",t,'document.readyState === "complete" && !!document.body && document.body.innerText.length > 500'])).trim()==="true")return}catch{}await new Promise((a)=>setTimeout(a,f))}}async function sa(t,n=8000){let f=Date.now(),p;try{p=await Rn()}catch(a){return{url:t,title:"",content:null,snippet:"",contentChars:0,error:`openNewTab failed: ${a.message}`,source:"browser",duration:Date.now()-f}}try{await M(["nav",p,t],30000),await mf(p);let a=await M(["eval",p,String.raw`
|
|
365
365
|
(function(){
|
|
366
366
|
var el = document.querySelector('article, [role="main"], main, .post-content, .article-body, #content, .content');
|
|
367
367
|
var text = (el || document.body).innerText;
|
|
@@ -371,116 +371,116 @@ ${g}`,pages:p.total}}catch(f){return{error:f.message||String(f)}}}function Ff(t=
|
|
|
371
371
|
url: location.href
|
|
372
372
|
});
|
|
373
373
|
})()
|
|
374
|
-
`]),
|
|
375
|
-
`);let
|
|
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(
|
|
374
|
+
`]),l=JSON.parse(a),g=Rt(l.content,n);return{url:t,finalUrl:l.url||t,status:200,contentType:"text/plain",lastModified:"",title:l.title,snippet:Gf(g,320),content:g,contentChars:g.length,source:"browser",duration:Date.now()-f}}catch(a){return{url:t,title:"",content:null,snippet:"",contentChars:0,error:a.message,source:"browser",duration:Date.now()-f}}finally{await yn(p)}}async function On(t,n=5,f=8000,p=bf){let a=t.slice(0,n);if(a.length===0)return[];let l=Math.min(a.length,Math.max(1,Number.parseInt(String(p),10)||bf));process.stderr.write(`[greedysearch] Fetching content from ${a.length} sources via HTTP (concurrency ${l})...
|
|
375
|
+
`);let g=Array(a.length),r=0,w=0;async function $(){while(!0){let e=r++;if(e>=a.length)return;let b=a[e],D=b.canonicalUrl||b.url;process.stderr.write(`[greedysearch] [${e+1}/${a.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(g[e]={id:b.id,...v},v.content&&v.content.length>100)process.stderr.write(`[greedysearch] ✓ ${v.source}: ${v.content.length} chars
|
|
377
377
|
`);else if(v.error)process.stderr.write(`[greedysearch] ✗ ${v.error.slice(0,80)}
|
|
378
|
-
`);w+=1,process.stderr.write(`PROGRESS:fetch:${w}/${
|
|
379
|
-
`)}}await Promise.all(Array.from({length:
|
|
380
|
-
`),
|
|
378
|
+
`);w+=1,process.stderr.write(`PROGRESS:fetch:${w}/${a.length}
|
|
379
|
+
`)}}await Promise.all(Array.from({length:l},()=>$()));let _=g.filter((e)=>e.content&&e.content.length>100),h=g.filter((e)=>e.source==="http").length,E=g.filter((e)=>e.source==="browser").length;return process.stderr.write(`[greedysearch] Fetched ${_.length}/${g.length} sources (HTTP: ${h}, Browser: ${E})
|
|
380
|
+
`),g}async function ua(t){let n=await Rn();try{await M(["nav",n,t],30000),await mf(n);let f=await M(["eval",n,String.raw`
|
|
381
381
|
(function(){
|
|
382
382
|
var el = document.querySelector('article, [role="main"], main, .post-content, .article-body, #content, .content');
|
|
383
383
|
var text = (el || document.body).innerText;
|
|
384
384
|
return text.replace(/\s+/g, ' ').trim();
|
|
385
385
|
})()
|
|
386
|
-
`]);return{url:t,content:f}}catch(f){return{url:t,content:null,error:f.message}}finally{await yn(n)}}var
|
|
386
|
+
`]);return{url:t,content:f}}catch(f){return{url:t,content:null,error:f.message}}finally{await yn(n)}}var cl,ql,Vt=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,pa,Oa,Na,ia,La,er,x,hr,Er,Dr,br,Cr,vr,jr,Pr,Rr,en,pt,hn,En="gemini",hf,ln,yr,Or,Nr,Ma,ir,z,Tr,Ar,kr,Hr,Lr,Yr,Ir,Fr,Gr,Dn,at,bn,Cn="gemini",Ef,rn,Mr,Wr,mr,Vr,Jr,Zr,Kr,M,Ba,Qr,S,xr,zr,Sr,cr,dr,qr,sr,ur,t0,vn,gt,jn,Pn="gemini",Df,wn,n0,f0,bf;var Xt=qt(()=>{cl=Jp(import.meta.url),ql=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"};pa={"user-agent":"GreedySearch/1.0 (Research Bot)",accept:"application/json"};Oa=$a(ea(import.meta.url)),Na=_a(Oa,"..","bin","cdp.mjs"),ia=new Set(["list","snap","eval","shot","html","nav","net","click","clickxy","type","loadall","evalraw","browse","stop","--tab"]);La=Ca().replaceAll("\\","/"),er=Ha(process.env.GREEDY_SEARCH_PORT),x=(process.env.GREEDY_SEARCH_PROFILE_DIR||process.env.CDP_PROFILE_DIR||`${La}/greedysearch-chrome-profile`).replaceAll("\\","/"),hr=`${x}/DevToolsActivePort`,Er=process.env.GREEDY_SEARCH_PID_FILE||`${x}/browser.pid`,Dr=process.env.CDP_PAGES_CACHE||`${x}/cdp-pages.json`,br=process.env.GREEDY_SEARCH_MODE_FILE||`${x}/browser-mode`,Cr=process.env.GREEDY_SEARCH_METADATA_FILE||`${x}/browser-metadata.json`,vr=process.env.GREEDY_SEARCH_LAUNCH_LOCK_FILE||`${x}/browser-launch.lock`,jr=process.env.GREEDY_SEARCH_ACTIVITY_FILE||`${x}/browser-last-activity`,Pr=(process.env.CDP_SOCKET_DIR||`${x}/cdp-sockets`).replaceAll("\\","/"),Rr=`${x}/visible-recovery.jsonl`,en=Af(ba(),".dm"),pt=Af(en,"greedyconfig"),hn=["perplexity","google","chatgpt","gemini"];Ia();hf=["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"},yr=Ya(),Or=Fa(),Nr=Math.max(1,Number.parseInt(process.env.GREEDY_FETCH_CONCURRENCY||"5",10)||5);process.env.CDP_PROFILE_DIR=x;Ma=Ra().replaceAll("\\","/"),ir=Ga(process.env.GREEDY_SEARCH_PORT),z=(process.env.GREEDY_SEARCH_PROFILE_DIR||process.env.CDP_PROFILE_DIR||`${Ma}/greedysearch-chrome-profile`).replaceAll("\\","/"),Tr=`${z}/DevToolsActivePort`,Ar=process.env.GREEDY_SEARCH_PID_FILE||`${z}/browser.pid`,kr=process.env.CDP_PAGES_CACHE||`${z}/cdp-pages.json`,Hr=process.env.GREEDY_SEARCH_MODE_FILE||`${z}/browser-mode`,Lr=process.env.GREEDY_SEARCH_METADATA_FILE||`${z}/browser-metadata.json`,Yr=process.env.GREEDY_SEARCH_LAUNCH_LOCK_FILE||`${z}/browser-launch.lock`,Ir=process.env.GREEDY_SEARCH_ACTIVITY_FILE||`${z}/browser-last-activity`,Fr=(process.env.CDP_SOCKET_DIR||`${z}/cdp-sockets`).replaceAll("\\","/"),Gr=`${z}/visible-recovery.jsonl`,Dn=Hf(Pa(),".dm"),at=Hf(Dn,"greedyconfig"),bn=["perplexity","google","chatgpt","gemini"];ma();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"},Mr=Wa(),Wr=Va(),mr=Math.max(1,Number.parseInt(process.env.GREEDY_FETCH_CONCURRENCY||"5",10)||5);process.env.CDP_PROFILE_DIR=z;Vr=Number.parseInt(process.env.GREEDY_SEARCH_IDLE_TIMEOUT_MINUTES||"5",10)||5,Jr=ka(import.meta.url),Zr=Number.parseInt(process.env.GREEDY_SEARCH_IDLE_TIMEOUT_MINUTES||"5",10)||5,Kr=Number.parseInt(process.env.GREEDY_SEARCH_VISIBLE_IDLE_TIMEOUT_MINUTES||"60",10)||60,M=Lf;Ba=Xa().replaceAll("\\","/"),Qr=oa(process.env.GREEDY_SEARCH_PORT),S=(process.env.GREEDY_SEARCH_PROFILE_DIR||process.env.CDP_PROFILE_DIR||`${Ba}/greedysearch-chrome-profile`).replaceAll("\\","/"),xr=`${S}/DevToolsActivePort`,zr=process.env.GREEDY_SEARCH_PID_FILE||`${S}/browser.pid`,Sr=process.env.CDP_PAGES_CACHE||`${S}/cdp-pages.json`,cr=process.env.GREEDY_SEARCH_MODE_FILE||`${S}/browser-mode`,dr=process.env.GREEDY_SEARCH_METADATA_FILE||`${S}/browser-metadata.json`,qr=process.env.GREEDY_SEARCH_LAUNCH_LOCK_FILE||`${S}/browser-launch.lock`,sr=process.env.GREEDY_SEARCH_ACTIVITY_FILE||`${S}/browser-last-activity`,ur=(process.env.CDP_SOCKET_DIR||`${S}/cdp-sockets`).replaceAll("\\","/"),t0=`${S}/visible-recovery.jsonl`,vn=Ff(Ka(),".dm"),gt=Ff(vn,"greedyconfig"),jn=["perplexity","google","chatgpt","gemini"];Qa();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"},n0=Ua(),f0=xa(),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:()=>vg});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,a]=f;if(f.length===2)return{owner:p,repo:a,type:"root"};if(f.length>=4&&(f[2]==="blob"||f[2]==="tree")){let l=f[2],g=f[3],r=f.slice(4).join("/");return{owner:p,repo:a,type:l,ref:g,path:r}}return null}catch{return null}}async function U(t,n=1e4){let f=new AbortController,p=setTimeout(()=>f.abort(),n);try{let a=await fetch(`https://api.github.com${t}`,{headers:Xf,signal:f.signal});if(clearTimeout(p),!a.ok)throw Error(`GitHub API ${a.status}: ${t}`);return await a.json()}catch(a){throw clearTimeout(p),a}}async function bg(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="",a){try{let l;if(f==="HEAD")if(a)l=await U(`/repos/${t}/${n}/git/ref/heads/${a}`).catch(()=>null);else l=await Promise.any([U(`/repos/${t}/${n}/git/ref/heads/main`),U(`/repos/${t}/${n}/git/ref/heads/master`)]).catch(()=>null);else l=await U(`/repos/${t}/${n}/git/ref/heads/${f}`).catch(()=>U(`/repos/${t}/${n}/git/ref/heads/master`).catch(()=>null));if(!l?.object?.sha)return[];let g=(await U(`/repos/${t}/${n}/git/commits/${l.object.sha}`)).tree.sha,r=(await U(`/repos/${t}/${n}/git/trees/${g}`)).tree||[];if(p)r=r.filter((w)=>w.path.startsWith(p));return r.slice(0,50).map((w)=>({path:w.path,type:w.type==="tree"?"dir":"file",size:w.size}))}catch{return[]}}async function Cg(t,n,f,p,a=1e4,l){let g=async(w)=>{let $=new AbortController,_=setTimeout(()=>$.abort(),a);try{let h=await fetch(w,{headers:{"user-agent":Xf["user-agent"]},signal:$.signal});if(clearTimeout(_),h.ok)return await h.text();throw Error("not ok")}catch{throw clearTimeout(_),Error("failed")}};if(!f||f==="HEAD"){if(l)try{return await g(`https://raw.githubusercontent.com/${t}/${n}/${l}/${p}`)}catch{return null}try{return await Promise.any([g(`https://raw.githubusercontent.com/${t}/${n}/main/${p}`),g(`https://raw.githubusercontent.com/${t}/${n}/master/${p}`)])}catch{return null}}let r=[`https://raw.githubusercontent.com/${t}/${n}/${f}/${p}`,`https://raw.githubusercontent.com/${t}/${n}/master/${p}`];for(let w of r)try{return await g(w)}catch{}return null}async function vg(t){let n=of(t);if(!n)return{ok:!1,error:"Not a valid GitHub URL"};let{owner:f,repo:p,type:a,ref:l,path:g}=n;try{if(a==="root"||a==="tree"&&!g){let r=await U(`/repos/${f}/${p}`),[w,$]=await Promise.allSettled([bg(f,p),Kf(f,p,l||"HEAD","",r.default_branch)]),_=w.status==="fulfilled"?w.value:"",h=$.status==="fulfilled"?$.value:[],E=r?.description?`
|
|
387
387
|
|
|
388
|
-
> ${
|
|
388
|
+
> ${r.description}`:"",e=r?.stargazers_count==null?"":` ⭐ ${r.stargazers_count}`,b=r?.language?` · ${r.language}`:"",D=`# ${f}/${p}${e}${b}${E}
|
|
389
389
|
|
|
390
390
|
`;if(_)D+=_.slice(0,6000);else D+=`[No README found]
|
|
391
391
|
|
|
392
392
|
Files:
|
|
393
|
-
${
|
|
394
|
-
`)}`;return{ok:!0,title:`${f}/${p}`,content:D,tree:
|
|
395
|
-
`);return{ok:!0,title:`${f}/${p}/${
|
|
393
|
+
${h.map((v)=>` ${v.type==="dir"?"\uD83D\uDCC1":"\uD83D\uDCC4"} ${v.path}`).join(`
|
|
394
|
+
`)}`;return{ok:!0,title:`${f}/${p}`,content:D,tree:h.slice(0,30)}}if(a==="blob"&&g){let r;if(!l||l==="HEAD")try{r=(await U(`/repos/${f}/${p}`)).default_branch}catch{r=void 0}let w=await Cg(f,p,l,g,1e4,r);if(w===null)return{ok:!1,error:`File not found: ${g}`};return{ok:!0,title:`${f}/${p}: ${g}`,content:w}}if(a==="tree"&&g){let r;if(!l||l==="HEAD")try{r=(await U(`/repos/${f}/${p}`)).default_branch}catch{r=void 0}let w=await Kf(f,p,l||"HEAD",g,r),$=w.map((_)=>` ${_.type==="dir"?"\uD83D\uDCC1":"\uD83D\uDCC4"} ${_.path}`).join(`
|
|
395
|
+
`);return{ok:!0,title:`${f}/${p}/${g}`,content:`[Directory: ${g}]
|
|
396
396
|
|
|
397
397
|
Files:
|
|
398
|
-
${$}`,tree:w}}return{ok:!1,error:"Unsupported GitHub URL type"}}catch(
|
|
398
|
+
${$}`,tree:w}}return{ok:!1,error:"Unsupported GitHub URL type"}}catch(r){return{ok:!1,error:r.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 jg}from"node:child_process";import{basename as rp}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=rp(n||"").toLowerCase();if(p==="node"||p==="node.exe")return n;return"node"}import{mkdirSync as Fn,writeFileSync as J}from"node:fs";import{join as Y}from"node:path";import{fileURLToPath as Pg}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),a=p.lastIndexOf(" ");return a>0?`${p.slice(0,a)}...`:`${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),a=/\d/.test(n);return n===n.toLowerCase()&&f<=4&&!p&&!a?"":n}function ut(t="",n=""){let f=st(t),p=st(n);if(!p)return f;if(!f)return p;let a=/^https?:\/\//i.test(f),l=/^https?:\/\//i.test(p);if(a&&!l)return p;if(!a&&l)return f;return p.length>f.length?p:f}function m(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 a of[...n.searchParams.keys()]){let l=a.toLowerCase();if(wp.includes(l)||l.startsWith("utm_"))n.searchParams.delete(a)}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 ep(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(),a=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")||a.includes("/paper/")||a.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")||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 hp(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 et(t){return t.smartScore*3+t.engineCount*5+hp(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 a=p.replace(/\.com$/,"");if(n.includes(a))f.push(p)}return[...new Set(f)]}function cn(t,n){return t===n||t.endsWith(`.${n}`)}function Tt(t,n=""){let f=new Map,p=Object.keys(t||{}).filter(($)=>!$.startsWith("_")),a=bp(n);for(let $ of p){let _=t[$];if(!_?.sources)continue;for(let h=0;h<_.sources.length;h++){let E=_.sources[h],e=m(E.url);if(!e||e.length<10)continue;let b=st(E.title||""),D=ep(e),v=tn(D,b,e),P=0;if(a.some((I)=>cn(D,I)))P+=10;if(v==="official-docs")P+=3;let R=e.toLowerCase();if(/\/docs\/|\/documentation\/|\.dev\/|\/api\/|\/reference\//.test(R))P+=2;let y=a.some((I)=>cn(D,I));if(v==="social"&&!y)P-=20;if(a.length>0){if(it(D,Dp))P-=3;else if(v==="community"&&!it(D,["stackoverflow.com","stackexchange.com"]))P-=1}let j=f.get(e)||{id:"",canonicalUrl:e,displayUrl:E.url||e,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||e,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:h+1,title:ut(j.perEngine[$]?.title||"",b)},f.set(e,j)}}let l=Array.from(f.values()).map(($)=>({...$,engineCount:$.engines.length})),g=l.filter(($)=>$.sourceType!=="social"),r=l.filter(($)=>$.sourceType==="social");return g.sort(($,_)=>{let h=et(_)-et($);if(h!==0)return h;return $.domain.localeCompare(_.domain)}),r.sort(($,_)=>{let h=et(_)-et($);if(h!==0)return h;return $.domain.localeCompare(_.domain)}),[...g,...r].slice(0,12).map(($,_)=>({...$,id:`S${_+1}`,title:$.title||$.domain||$.canonicalUrl}))}function Gt(t,n){let f=new Map(n.map((p)=>[p.id,p]));return t.map((p)=>{let a=f.get(p.id);if(!a)return p;let l=ut(p.title,a.title||"");return{...p,title:l||p.title,fetch:{attempted:!0,ok:!a.error&&a.contentChars>100,status:a.status||null,finalUrl:a.finalUrl||a.url||p.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 Mt,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("\\","/"),El=Rp(process.env.GREEDY_SEARCH_PORT),K=(process.env.GREEDY_SEARCH_PROFILE_DIR||process.env.CDP_PROFILE_DIR||`${yp}/greedysearch-chrome-profile`).replaceAll("\\","/"),Dl=`${K}/DevToolsActivePort`,bl=process.env.GREEDY_SEARCH_PID_FILE||`${K}/browser.pid`,Cl=process.env.CDP_PAGES_CACHE||`${K}/cdp-pages.json`,vl=process.env.GREEDY_SEARCH_MODE_FILE||`${K}/browser-mode`,jl=process.env.GREEDY_SEARCH_METADATA_FILE||`${K}/browser-metadata.json`,Pl=process.env.GREEDY_SEARCH_LAUNCH_LOCK_FILE||`${K}/browser-launch.lock`,Rl=process.env.GREEDY_SEARCH_ACTIVITY_FILE||`${K}/browser-last-activity`,yl=(process.env.CDP_SOCKET_DIR||`${K}/cdp-sockets`).replaceAll("\\","/"),Ol=`${K}/visible-recovery.jsonl`,fn=sn(jp(),".dm"),nt=sn(fn,"greedyconfig"),pn=["perplexity","google","chatgpt","gemini"],an="gemini";function Op(){try{if(Mt(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((a)=>nn[a]),p=n.engines.filter((a)=>!nn[a]);if(p.length>0)process.stderr.write(`[greedysearch] Warning: ignoring unknown engine(s) in ${nt}: ${p.join(", ")}
|
|
399
399
|
[greedysearch] Available engines: ${Object.keys(nn).join(", ")}
|
|
400
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(!
|
|
402
|
-
`,"utf8")}catch{}}Np();var
|
|
403
|
-
[greedysearch] Available synthesizers: ${
|
|
404
|
-
[greedysearch] Falling back to default: ${
|
|
405
|
-
`)}}}catch{}return
|
|
406
|
-
`)n+="\\n";else if(f&&
|
|
407
|
-
`);try{let f=await X(n,{timeoutMs:
|
|
408
|
-
`),{complexity:"moderate",reasoning:"classification failed",suggestedBreadth:3,suggestedIterations:2,needsAcademicSources:!1}}}
|
|
409
|
-
`)}return{startRound(P){
|
|
410
|
-
`);$=E.pop()||"";for(let
|
|
411
|
-
`)});let _=setTimeout(()=>{
|
|
412
|
-
`);let E=ot({totalActions:6,totalRounds:1,totalFetches:1,silent:process.env.GREEDY_RESEARCH_QUIET==="1"});E.startRound(1);let
|
|
401
|
+
`)}}}catch{}return pn}function Np(){try{if(!Mt(fn))Cp(fn,{recursive:!0});if(!Mt(nt))vp(nt,JSON.stringify({engines:pn,synthesizer:an},null,2)+`
|
|
402
|
+
`,"utf8")}catch{}}Np();var At=["gemini","chatgpt"];function ip(){try{if(Mt(nt)){let t=qn(nt,"utf8"),n=JSON.parse(t);if(typeof n.synthesizer==="string"){let f=n.synthesizer.toLowerCase();if(At.includes(f))return f;process.stderr.write(`[greedysearch] Warning: unknown synthesizer "${n.synthesizer}" in ${nt}
|
|
403
|
+
[greedysearch] Available synthesizers: ${At.join(", ")}
|
|
404
|
+
[greedysearch] Falling back to default: ${an}
|
|
405
|
+
`)}}}catch{}return an}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,Nl=ip(),il=Math.max(1,Number.parseInt(process.env.GREEDY_FETCH_CONCURRENCY||"5",10)||5);process.env.CDP_PROFILE_DIR=K;function Tp(t){let n="",f=!1,p=!1;for(let a of String(t)){if(p){n+=a,p=!1;continue}if(a==="\\"){n+=a,p=!0;continue}if(a==='"'){f=!f,n+=a;continue}if(f&&a===`
|
|
406
|
+
`)n+="\\n";else if(f&&a==="\r")n+="\\r";else if(f&&a==="\t")n+="\\t";else n+=a}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 r=n.indexOf("{");if(r>0)n=n.slice(r)}let a=[n,n.replace(/^```json\s*/i,"").replace(/^```\s*/i,"").replace(/```$/i,"").trim()],l=n.indexOf("{"),g=n.lastIndexOf("}");if(l!==-1&&g!==-1&&l<g)a.push(n.slice(l,g+1));for(let r of[...a]){let w=Tp(r);if(w!==r)a.push(w)}for(let r of a)try{return JSON.parse(r)}catch{}return null}import{spawn as Lp}from"node:child_process";import{existsSync as un}from"node:fs";import{dirname as Ap,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:a=un}={}){let l=f?Ap(f):null,g=p.GREEDY_SEARCH_EXTENSION_DIR?.trim()||null;return Hp([n?Wt(n,"..","..","extractors",t):null,n?Wt(n,"..","extractors",t):null,g?Wt(g,"extractors",t):null,l?Wt(l,"..","extractors",t):null],a)}var Yp=tf(import.meta.url),Ip={gemini:"gemini.mjs",chatgpt:"chatgpt.mjs"};function Fp(t="gemini"){let n=String(t||"gemini").toLowerCase();if(n==="gem")return"gemini";if(n==="gpt")return"chatgpt";return n}async function Gp(t,n,{tabPrefix:f=null,timeoutMs:p=180000,visible:a=null}={}){let l=Fp(t),g=Ip[l];if(!g||!At.includes(l))throw Error(`Unsupported synthesizer "${t}". Supported: ${At.join(", ")}`);return new Promise((r,w)=>{let $=nf(g,{moduleDir:Yp}),_=f?["--tab",String(f)]:[],h={...process.env,CDP_PROFILE_DIR:K};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 E=Lp(jt(),[$,"--stdin",..._],{stdio:["pipe","pipe","pipe"],env:h});E.stdin.write(n),E.stdin.end();let e="",b="";E.stdout.on("data",(v)=>e+=v),E.stderr.on("data",(v)=>b+=v);let D=setTimeout(()=>{E.kill(),w(Error(`${l} prompt timed out after ${p/1000}s`))},p);E.on("close",(v)=>{if(clearTimeout(D),v!==0){w(Error(b.trim()||`${l} extractor failed`));return}try{r(JSON.parse(e.trim()))}catch{w(Error(`bad JSON from ${l}: ${e.slice(0,100)}`))}})})}async function X(t,n={}){return Gp("gemini",t,n)}var Mp=30000;function ff(t,n,f,p){let a=Number.parseInt(String(t??""),10);if(!Number.isFinite(a))return p;return Math.min(f,Math.max(n,a))}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:Mp}),p=ft(f?.answer||"")||{},a=["simple","moderate","complex"].includes(p.complexity)?p.complexity:"moderate";return{complexity:a,reasoning:H(p.reasoning||"",200),suggestedBreadth:ff(p.suggestedBreadth,1,5,a==="simple"?1:3),suggestedIterations:ff(p.suggestedIterations,1,3,a==="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}}}gn();Xt();function tg(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 ng(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 a=Date.now(),l=0,g=0,r=0,w=[],$=null,_=null,h=0,E=500;function e(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()-a,y=t+f+n,j=l+r+g,I=y>0?Math.min(1,j/y):0,F=ng(I),T=b(),k=Math.max(0,y-j),G=T?T*k:null,ht=G?tg(G):"—",d=_?` ${_}`:"";return`${F} ${j}/${y} (${P}${d}, ETA ${ht})`}function v(P){if(p)return;let R=Date.now();if(R-h<E&&P!=="done")return;h=R,process.stderr.write(`[greedysearch] ${D(P)}
|
|
409
|
+
`)}return{startRound(P){g=P-1},endRound(){g++,v("round")},startAction(P,R){$=Date.now(),_=`${P}:${(R||"").slice(0,40)}`,v(P)},endAction(){if($)e(Date.now()-$),$=null;l++,v("action")},startFetch(P){$=Date.now(),_=`fetch:${(P||"").slice(0,40)}`,v("fetch")},endFetch(P=!0){if($)e(Date.now()-$),$=null;r++,v(P?"fetch":"fetch-failed")},print(){v("progress")},finish(){v("done")},getElapsedMs(){return Date.now()-a}}}import{spawn as fg}from"node:child_process";import{join as pg}from"node:path";import{fileURLToPath as ag}from"node:url";var gg=ag(new URL(".",import.meta.url)).replace(/^\/([A-Z]:)/,"$1"),lg=pg(gg,"..","..","bin","search.mjs");function Vf(t,n=1/0){let f=new Set,p=[];for(let a of t||[]){let l=H(String(a||""),1000);if(!l||f.has(l))continue;if(f.add(l),p.push(l),p.length>=n)break}return p}function rg(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 wg(t,n){let f=new Map;for(let p of t||[]){let a=p?.canonicalUrl||p?.finalUrl||p?.url;if(a)f.set(a,p)}for(let p of n||[]){let a=p?.canonicalUrl||p?.finalUrl||p?.url;if(!a)continue;if(f.has(a)){let l={...f.get(a),angles:[...f.get(a).angles||[f.get(a).query||""],p.query||""]};f.set(a,l)}else f.set(a,p)}return Array.from(f.values())}var $g=Pt.join("|"),_g=new RegExp(`^\\[(${$g})\\]`);function eg(t){return/^PROGRESS:/.test(t)||/^\[greedysearch\]/.test(t)||_g.test(t)||/^GreedySearch Chrome/.test(t)||/^Launching GreedySearch Chrome/.test(t)||/^Headless mode/.test(t)||/^Ready\.?$/.test(t)}async function hg(t,{locale:n=null,short:f=!0}={}){let p=[lg,"all","--inline","--stdin","--fast"];if(!f)p.push("--full");if(n)p.push("--locale",n);return new Promise((a,l)=>{let g=fg(jt(),p,{stdio:["pipe","pipe","pipe"],env:{...process.env,GREEDY_SEARCH_RESEARCH_CHILD:"1"}});g.stdin.write(t),g.stdin.end();let r="",w="",$="";g.stdout.on("data",(h)=>r+=h),g.stderr.on("data",(h)=>{w+=h,$+=h.toString();let E=$.split(`
|
|
410
|
+
`);$=E.pop()||"";for(let e of E)if(eg(e))process.stderr.write(`${e}
|
|
411
|
+
`)});let _=setTimeout(()=>{g.kill(),l(Error(`research child search timed out for: ${t}`))},140000);g.on("close",(h)=>{if(clearTimeout(_),h!==0){l(Error(w.trim()||`search child exited with code ${h}`));return}try{a(JSON.parse(r.trim()))}catch{l(Error(`Invalid JSON from research child: ${r.slice(0,200)}`))}})})}function Eg(t,n){let f=new Map;for(let p of n||[]){let a=m(p?.canonicalUrl||p?.finalUrl||p?.url);if(a&&p?.id)f.set(a,p.id)}return(t||[]).map((p,a)=>{let l=m(p?.finalUrl||p?.canonicalUrl||p?.url);return{...p,id:p?.id||f.get(l)||`F${a+1}`}})}function Dg(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:a=process.env.GREEDY_RESEARCH_BUNDLE!=="0",researchOutDir:l=null}={}){let g=new Date().toISOString(),r=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 e=[],b=[],D=rg(t),v=[];E.startAction("search",`${D.length} angles in parallel`);let P=await Promise.allSettled(D.map((N)=>hg(N,{locale:n,short:!0})));for(let N=0;N<D.length;N++){let o=D[N],rt=P[N];if(E.endAction(),rt.status==="fulfilled"){let Z=rt.value;v.push({angle:o,result:Z});let A=Tt(Z,o);e=wg(e,A)}else process.stderr.write(`[greedysearch] Simple search angle "${o}" failed: ${rt.reason.message}
|
|
413
413
|
`)}if(process.stderr.write(`PROGRESS:research:simple:fetching
|
|
414
|
-
`),
|
|
415
|
-
`)}b=
|
|
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
|
|
414
|
+
`),e.length>0)try{E.startFetch(`top ${Math.min(f,e.length)} sources`),b=await On(e,Math.min(f,e.length),8000,Math.min(3,f)),E.endFetch(!0),e=Gt(e,b)}catch(N){E.endFetch(!1),process.stderr.write(`[greedysearch] Source fetching failed: ${N.message}
|
|
415
|
+
`)}b=Eg(b,e),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 rt=Array.isArray(o.answers)?o.answers:[];for(let A of rt){let $t=A?.id||A?.question;if($t){let q=w.find((xt)=>xt.id===$t);if(q){if(q.status="closed",q.closedRound=1,A.evidence)q.evidence=Vf([...q.evidence||[],A.evidence],4)}}}let Z=Array.isArray(o.newQuestions)?o.newQuestions:[];for(let A of Z){let $t=H(String(A),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
417
|
`)}process.stderr.write(`PROGRESS:research:simple:synthesizing
|
|
418
|
-
`);let y={answer:"",agreement:{level:"mixed",summary:"Single-pass synthesis."},differences:[],caveats:[],claims:[],recommendedSources:
|
|
419
|
-
`)}if(!y.synthesized&&
|
|
418
|
+
`);let y={answer:"",agreement:{level:"mixed",summary:"Single-pass synthesis."},differences:[],caveats:[],claims:[],recommendedSources:e.slice(0,4).map((N)=>N.id),synthesized:!1};if(R.length>0)try{E.startAction("synth-evidence","from evidence");let N=await X(An(t,e,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&&e.length>0)try{E.startAction("synth-final","fallback report");let N=await X(Tn(t,[{round:1,learnings:[],gaps:[],actions:[]}],e,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
420
|
`)}process.stderr.write(`PROGRESS:research:simple:audit
|
|
421
|
-
`);let j=kn(y.answer||"",
|
|
422
|
-
`);try{d=await In({query:t,rounds:[{round:1,actions:[],learnings:[],gaps:
|
|
423
|
-
`),d={error:N.message||String(N)},wt=await
|
|
424
|
-
`),E.endRound(),E.finish(),{query:t,_research:{mode:"simple",breadth:1,iterations:1,maxSources:f,rounds:[{round:1,actions:[],learnings:[],gaps:
|
|
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),
|
|
426
|
-
`)}function
|
|
427
|
-
`),{score:
|
|
421
|
+
`);let j=kn(y.answer||"",e),I=await Hn(e,j);Yn(w,y,j);let F=Vf(y.caveats||[]),T=Bt({sources:e,fetchedSources:b,synthesis:y,citationAudit:j,gaps:F,questions:w,rounds:[{round:1,actions:[],learnings:[],gaps:F}],qualityScore:y.synthesized?8:5,qualityThreshold:p,maxSources:f}),k=new Date().toISOString(),G=Date.now()-r,ht={startedAt:g,finishedAt:k,durationMs:G,rounds:1,terminationReason:"simple_single_pass"},d=null,wt;if(a){process.stderr.write(`PROGRESS:research:simple:bundle
|
|
422
|
+
`);try{d=await In({query:t,rounds:[{round:1,actions:[],learnings:[],gaps:F,evidence:R}],sources:e,fetchedSources:b,evidenceItems:R,synthesis:y,citationAudit:j,citationUrls:I,floor:T,manifest:{...ht,engines:kt,synthesizer:"gemini",actionsRun:1,searches:1,fetches:b.length,sourcesFetched:b.filter((N)=>N?.contentChars>100).length,engineFailures:[],floorMet:T.floorMet},allGaps:F,questions:w,outDir:l}),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 mt(b)}}else wt=await mt(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:F,evidence:R}],learnings:[],gaps:F,evidence:R,questions:w,questionProgress:Dg(w),qualityHistory:[y.synthesized?8:5],terminationReason:"simple_single_pass",qualityThreshold:p,floor:T,bundle:d,manifest:ht},_citationAudit:j,_citationUrls:I,_sources:e,_fetchedSources:wt,_synthesis:y,_confidence:{sourcesCount:e.length,fetchedSourceSuccessRate:b.length>0?b.filter((N)=>N.contentChars>100).length/b.length:0,agreementLevel:y.agreement?.level||"mixed",floorMet:T.floorMet}}}var Rg=Pg(new URL(".",import.meta.url)).replace(/^\/([A-Z]:)/,"$1"),yg=Y(Rg,"..","..","bin","search.mjs"),Og=Y(process.cwd(),".pi","greedysearch-research"),Ng=28000;function ig(t){return String(t||"research").toLowerCase().replaceAll(/[^a-z0-9]+/g,"-").replaceAll(/^-|-$/g,"").slice(0,60)||"research"}function lt(t,n=1/0){let f=new Set,p=[];for(let a of t||[]){let l=H(String(a||""),1000);if(!l||f.has(l))continue;if(f.add(l),p.push(l),p.length>=n)break}return p}async function Tg(...t){let{fetchMultipleSources:n}=await Promise.resolve().then(() => (Xt(),Nn));return n(...t)}async function Vn(...t){let{writeSourcesToFiles:n}=await Promise.resolve().then(() => (gn(),gf));return n(...t)}function Ag({breadth:t=3,iterations:n=2,maxSources:f}){let p=Gn(t,1,5,3),a=Gn(n,1,3,2),l=Gn(f??Math.max(5,p*a*2),3,12,8);return{breadth:p,iterations:a,maxSources:l}}function Gn(t,n,f,p){let a=Number.parseInt(String(t??""),10);if(!Number.isFinite(a))return p;return Math.min(f,Math.max(n,a))}function kg(t,n,f,{expand:p=!0,includeOriginal:a=!0,exclude:l=[]}={}){let g=Array.isArray(t?.queries)?t.queries:[],r=[],w=new Set([...l].map(($)=>c($).toLowerCase()));for(let $ of g){let _=typeof $==="string"?$:$?.query,h=typeof $==="string"?"":$?.researchGoal||"";Mn(r,_,h,{exclude:w})}if(a)Mn(r,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(r.length>=f)break;Mn(r,_.query,_.researchGoal,{exclude:w})}}return r.slice(0,f)}function Mn(t,n,f="",{prepend:p=!1,exclude:a=new Set}={}){if(!n||typeof n!=="string")return;let l=c(n);if(!l||a.has(l.toLowerCase())||t.some((r)=>r.query.toLowerCase()===l.toLowerCase()))return;let g={query:l,researchGoal:H(f,320)};if(p)t.unshift(g);else t.push(g)}function c(t){return Lg(Hg(String(t)))}function Hg(t){let n="",f=0;while(f<t.length){let p=t.indexOf("[",f);if(p===-1){n+=t.slice(f);break}let a=t.indexOf("]",p+1);if(a===-1||t[a+1]!=="("||a===p+1){n+=t.slice(f,p+1),f=p+1;continue}let l=t.indexOf(")",a+2);if(l===-1){n+=t.slice(f,p+1),f=p+1;continue}let g=t.slice(a+2,l).trimStart();if(!g.startsWith("http://")&&!g.startsWith("https://")){n+=t.slice(f,p+1),f=p+1;continue}n+=t.slice(f,p),n+=t.slice(p+1,a),f=l+1}return n}function Lg(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),a=new Set([...f,...p]).size;if(a===0)return 1;let l=0;for(let g of f)if(p.has(g))l++;return l/a}function zf(t,n,{threshold:f=0.75,roundIndex:p=0,originalQuery:a=null}={}){let l=c(t).toLowerCase();if(n.has(l))return!0;if(a&&p>0&&l===c(a).toLowerCase())return!0;for(let g of n)if(Kn(l,g)>=f)return!0;return!1}function Yg(t,n,f,p){let a=n.map((l)=>({queries:l.queries?.map((g)=>g.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(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 Ig(t,n,f,p,a){let l=[],g=[{template:(r)=>`${r} official documentation`,label:"official docs"},{template:(r)=>`${r} GitHub issues discussions`,label:"community signals"},{template:(r)=>`${r} benchmarks performance comparison`,label:"benchmarks"},{template:(r)=>`${r} limitations risks caveats`,label:"limitations"},{template:(r)=>`${r} production deployment experience`,label:"production usage"},{template:(r)=>`${n} ${r} counter evidence`,label:"counter-evidence"}];for(let r=0;r<t.length&&l.length<p;r++){let w=t[r],$=g[r%g.length],_=$.template(w);if(!zf(_,f,{roundIndex:a}))l.push({query:_,researchGoal:`Gap-driven: ${w} (${$.label})`})}return l}async function Fg(t,n,f,p,a){try{let l=await X(Yg(t,n,f,p),{timeoutMs:120000}),g=Ht(l,{}),r=typeof g.score==="number"?Math.min(10,Math.max(0,g.score)):a.length>0?a[a.length-1]:5,w=Array.isArray(g.knowledgeGaps)?g.knowledgeGaps.map((E)=>String(E)).filter(Boolean).slice(0,6):[],$=Array.isArray(g.nextActions)?g.nextActions.slice(0,5):[],_=typeof g.shouldContinue==="boolean"?g.shouldContinue:r<8,h=g.terminationReason||null;return{score:r,coverage:g.coverage||{},knowledgeGaps:w,shouldContinue:_,nextActions:$,terminationReason:h||(r>=8.5?"quality_threshold":null),evaluationError:""}}catch(l){return process.stderr.write(`[greedysearch] Quality evaluation failed: ${l.message}
|
|
427
|
+
`),{score:a.length>0?a[a.length-1]:5,coverage:{},knowledgeGaps:[],shouldContinue:!0,nextActions:[],terminationReason:null,evaluationError:l.message}}}function Gg(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((a)=>({title:H(a.title||"",160),url:a.url||""})):[]}}return n}function Mg(t,n,f=[],p=[],a=[]){let l=p.length>0?`
|
|
428
428
|
Known knowledge gaps to target:
|
|
429
|
-
${p.map((
|
|
430
|
-
`)}`:"",a
|
|
429
|
+
${p.map((r)=>`- ${r}`).join(`
|
|
430
|
+
`)}`:"",g=a.length>0?`
|
|
431
431
|
Already fetched URLs (do not re-fetch):
|
|
432
|
-
${
|
|
432
|
+
${a.map((r)=>`- ${r}`).join(`
|
|
433
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?`
|
|
434
434
|
Prior learnings to build on:
|
|
435
|
-
${f.map((
|
|
436
|
-
`)}`:"",
|
|
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=
|
|
438
|
-
`)}async function Zf({query:t,questions:n,fetchedSources:f,extractedSourceKeys:p}){let
|
|
439
|
-
`)},
|
|
440
|
-
`)}function
|
|
441
|
-
`)}async function
|
|
442
|
-
`);$=E.pop()||"";for(let
|
|
443
|
-
`)});let _=setTimeout(()=>{
|
|
444
|
-
`);try{let f=new Set(n?.cited||[]),p=f.size?(t||[]).filter((
|
|
445
|
-
`);return
|
|
446
|
-
`),null}}function Bt({sources:t=[],fetchedSources:n=[],synthesis:f={},citationAudit:p=null,gaps:
|
|
447
|
-
`)}function
|
|
448
|
-
`):n}function
|
|
449
|
-
`),"utf8")}async function In({query:t,rounds:n,sources:f,fetchedSources:p,evidenceItems:
|
|
435
|
+
${f.map((r)=>`- ${r}`).join(`
|
|
436
|
+
`)}`:"",l,g,"","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=m(t.url);return p?{type:"fetchUrl",url:p,researchGoal:f}:null}return null}async function Wg(t,{locale:n=null,short:f=!0,usedQueries:p,usedUrls:a,maxChars:l=8000}={}){if(t.type==="search"){let g=c(t.query).toLowerCase();p.add(g);try{let r=await Ug(t.query,{locale:n,short:f}),w=Tt(r,t.query);return{ok:!0,action:t,result:r,sources:w}}catch(r){return{ok:!1,action:t,error:r.message,sources:[]}}}if(t.type==="fetchUrl"){let g=m(t.url);if(a.has(g))return{ok:!1,action:t,error:`URL already fetched: ${g}`,sources:[]};try{let r=await mg(g,l);a.add(g);let w=Vg(g),$={id:"",canonicalUrl:r.finalUrl||g,displayUrl:r.url||g,domain:w,title:r.title||g,engines:["fetch"],engineCount:1,perEngine:{},sourceType:tn(w,r.title||"",r.finalUrl||g),isOfficial:!1,smartScore:0,fetch:{attempted:!0,ok:!r.error&&(r.contentChars||0)>100,status:r.status||null,finalUrl:r.finalUrl||g,content:r.content||"",contentChars:r.contentChars||0,snippet:r.snippet||"",error:r.error||""}};return{ok:!0,action:t,result:null,sources:[$],fetchResult:{id:$.id,url:g,finalUrl:r.finalUrl||g,title:r.title||"",content:r.content||"",contentChars:r.contentChars||0,snippet:r.snippet||"",status:r.status||null,error:r.error||"",source:r.source||"http",duration:r.duration||0}}}catch(r){return{ok:!1,action:t,error:r.message,sources:[]}}}return{ok:!1,action:t,error:`Unknown action type: ${t.type}`,sources:[]}}async function mg(t,n){let{fetchSourceContent:f}=await Promise.resolve().then(() => (Xt(),Nn));return await f(t,n)}function Vg(t){try{return new URL(t).hostname.toLowerCase().replace(/^www\./,"")}catch{return""}}async function Jg(t,n){let f=[],{parseGitHubUrl:p}=await Promise.resolve().then(() => (Uf(),Bf));for(let a of t){if(a.type!=="fetchUrl"){f.push(a);continue}let l=p(a.url);if(!l||l.type!=="root"){f.push(a);continue}let{owner:g,repo:r}=l,w=`https://github.com/${g}/${r}`;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 h of _){if($.length>=3)break;if(!n.has(h))$.push(h)}for(let h of $)f.push({type:"fetchUrl",url:h,researchGoal:a.researchGoal||`Fetch GitHub content for ${g}/${r}`})}return f}function Zg(t,n){let f=ft(t?.answer||"")||{},p=Array.isArray(f?.actions)?f.actions:[],a=[];for(let l of p){let g=Sf(l);if(g&&a.length<n)a.push(g)}return a}function Kg(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 m(t?.finalUrl||t?.canonicalUrl||t?.url||"")||t?.id||""}function cf(t,n){let f=Array.isArray(t?.extractions)?t.extractions:[],p=new Map,a=new Map;for(let l of n||[]){if(l?.id)a.set(String(l.id),l);let g=yt(l);if(g)p.set(g,l)}return f.map((l)=>{let g=a.get(String(l?.sourceId||""))||p.get(m(l?.url||"")||""),r=String(l?.sourceId||g?.id||""),w=m(l?.url||g?.finalUrl||g?.url||""),$=Array.isArray(l?.answers)?l.answers.map((_)=>({id:String(_?.id||""),evidence:H(_?.evidence||"",500),sourceIds:[r].filter(Boolean)})).filter((_)=>_.id):[];return{sourceId:r,url:w,title:g?.title||l?.title||"",rational:H(l?.rational||"",700),evidence:H(l?.evidence||"",1600),summary:H(l?.summary||"",700),answers:$,newQuestions:lt(l?.newQuestions||[],6)}}).filter((l)=>l.sourceId||l.url||l.summary||l.evidence)}function Xg(t,n,f,p=new Set){let a=(n||[]).filter((g)=>g.status!=="closed").slice(0,12).map((g)=>({id:g.id,question:g.question})),l=(f||[]).filter((g)=>g?.content||g?.snippet).filter((g)=>!p.has(yt(g))).slice(0,6).map((g,r)=>({id:g.id||`F${r+1}`,title:g.title||"",url:g.finalUrl||g.url||g.canonicalUrl||"",content:H(g.content||g.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(`
|
|
438
|
+
`)}async function Zf({query:t,questions:n,fetchedSources:f,extractedSourceKeys:p}){let a=(f||[]).filter((l)=>(l?.content||l?.snippet)&&!p.has(yt(l)));if(a.length===0)return{evidence:[],error:""};try{let l=await X(Xg(t,n,a,p),{timeoutMs:120000}),g=Ht(l,{extractions:[]}),r=cf(g,a);for(let w of a){let $=yt(w);if($)p.add($)}return{evidence:r,error:""}}catch(l){return{evidence:[],error:l.message||String(l)}}}function og(t,n,f,p,a,l,g=[]){let r=(n||[]).filter((R)=>R.status!=="closed").slice(0,12).map((R)=>({id:R.id,question:R.question})),w=(a||[]).filter((R)=>R?.content||R?.snippet),$=(l||[]).filter((R)=>R?.content||R?.snippet),_=({extractionCount:R,extractionLimit:y,learningCount:j,learningLimit:I})=>{let F=w.slice(0,R).map((k,G)=>({id:k.id||`F${G+1}`,title:k.title||"",url:k.finalUrl||k.url||k.canonicalUrl||"",content:H(k.content||k.snippet||"",y)})),T=$.slice(0,j).map((k,G)=>({id:`F${G+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(r)}`,`Round queries: ${JSON.stringify(f)}`,`Question ledger: ${JSON.stringify(n)}`,`Extracted source evidence so far: ${JSON.stringify(g.slice(-12))}`,`Engine summaries: ${JSON.stringify(p)}`,`Sources for evidence extraction (Task A): ${JSON.stringify(F)}`,`Fetched source snippets (Task B context): ${JSON.stringify(T)}`,"","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
|
+
`)},h=Math.min(4,w.length),E=3000,e=Math.min(6,$.length),b=2000,D=_({extractionCount:h,extractionLimit:E,learningCount:e,learningLimit:b}),v=!1,P=600;while(D.length>Ng){if(E>P||b>P)E=Math.max(P,Math.floor(E/2)),b=Math.max(P,Math.floor(b/2));else if(e>1)e-=1;else if(h>1)h-=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:h,extractionLimit:E,learningCount:e,learningLimit:b})}if(v)console.error(`[greedysearch] evidence/learning prompt trimmed to fit Gemini input cap: ${D.length} chars`);return D}async function Bg({query:t,questions:n,fetchedSources:f,extractedSourceKeys:p,roundQueries:a,searchSummaries:l,evidenceItems:g=[]}){let r=(f||[]).filter((E)=>(E?.content||E?.snippet)&&!p.has(yt(E))),w=[],$="",_={learnings:[],followUpQueries:[],gaps:[]},h="";try{let E=await X(og(t,n,a,l,r,f,g),{timeoutMs:180000}),e=Ht(E,{});w=cf(e,r);for(let b of r){let D=yt(b);if(D)p.add(D)}_={..._,...e}}catch(E){let e=E.message||String(E);$=e,h=e}return{evidence:w,evidenceError:$,learningPayload:_,learningError:h}}function Tn(t,n,f,p=[],a=[]){let l=n.flatMap((w)=>w.learnings||[]),g=n.flatMap((w)=>w.gaps||[]),r=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(l,null,2)}`,`Known gaps/caveats: ${JSON.stringify(g,null,2)}`,`Question ledger: ${JSON.stringify(p,null,2)}`,`Goal-based extracted evidence: ${JSON.stringify(a.slice(-20),null,2)}`,`Source registry: ${JSON.stringify(r,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 An(t,n=[],f=[],p=[]){let a=n.slice(0,12).map((w)=>({id:w.id,title:w.title,domain:w.domain,url:w.canonicalUrl,type:w.sourceType,engines:w.engines})),l=p.slice(-20),g=new Set;for(let w of l)for(let $ of w.answers||[])if($?.id)g.add($.id);let r=(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(l,null,2)}`,`Source registry: ${JSON.stringify(a,null,2)}`,`Questions already answered by the evidence: ${JSON.stringify(Array.from(g))}`,`Questions still open after this evidence: ${JSON.stringify(r)}`,"","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 Ug(t,{locale:n=null,short:f=!0}={}){let p=[yg,"all","--inline","--stdin","--fast"];if(!f)p.push("--full");if(n)p.push("--locale",n);return new Promise((a,l)=>{let g=jg(jt(),p,{stdio:["pipe","pipe","pipe"],env:{...process.env,GREEDY_SEARCH_RESEARCH_CHILD:"1"}});g.stdin.write(t),g.stdin.end();let r="",w="",$="";g.stdout.on("data",(h)=>r+=h),g.stderr.on("data",(h)=>{w+=h,$+=h.toString();let E=$.split(`
|
|
442
|
+
`);$=E.pop()||"";for(let e of E)if(Sg(e))process.stderr.write(`${e}
|
|
443
|
+
`)});let _=setTimeout(()=>{g.kill(),l(Error(`research child search timed out for: ${t}`))},140000);g.on("close",(h)=>{if(clearTimeout(_),h!==0){l(Error(w.trim()||`search child exited with code ${h}`));return}try{a(JSON.parse(r.trim()))}catch{l(Error(`Invalid JSON from research child: ${r.slice(0,200)}`))}})})}function Qg(t){let n=new Map;for(let f of t.flat()){let p=m(f.canonicalUrl||f.url);if(!p)continue;let a=n.get(p);if(!a){n.set(p,{...f,canonicalUrl:p});continue}a.engines=[...new Set([...a.engines||[],...f.engines||[]])],a.engineCount=a.engines.length,a.smartScore=Math.max(a.smartScore||0,f.smartScore||0)}return Array.from(n.values()).sort((f,p)=>{let a=et(p)-et(f);if(a!==0)return a;return(f.domain||"").localeCompare(p.domain||"")}).slice(0,12).map((f,p)=>({...f,id:`S${p+1}`}))}var xg=Pt.join("|"),zg=new RegExp(`^\\[(${xg})\\]`);function Sg(t){return/^PROGRESS:/.test(t)||/^\[greedysearch\]/.test(t)||zg.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,a;while((a=f.exec(t))!==null)p.add(`S${a[1]}`),p.add(`F${a[1]}`);let l=new Map;for(let $ of n){let _=$?.id;if(_)l.set(_,$)}let g=Array.from(p),r=[],w=[];for(let $ of g){let _=l.get($);if(!_){let h=$.match(/^(S|F)(\d+)$/);if(h){let E=parseInt(h[2],10)-1;if(E>=0&&E<n.length){let e=n[E];if(e){if(!(e.fetch?.ok||e.content&&e.content.length>100||e.contentChars&&e.contentChars>100))w.push($);continue}}}r.push($)}else if(!(_.fetch?.ok||_.content&&_.content.length>100||_.contentChars&&_.contentChars>100))w.push($)}return{cited:g,missing:r,unfetched:w,ok:r.length===0}}async function cg(t,{timeoutMs:n=6000,concurrency:f=4}={}){let p=Math.max(1,Math.floor(f||1)),a=(t||[]).filter((E)=>E?.id&&(E?.canonicalUrl||E?.finalUrl||E?.url));if(a.length===0)return{reachable:[],dead:[],skipped:[],ok:!0};let l=[],g=[],r=[],w=Array(a.length),$=0;async function _(){while(!0){let E=$++;if(E>=a.length)return;let e=a[E];try{let b=e.fetch?.finalUrl||e.canonicalUrl||e.finalUrl||e.url;if(!b){w[E]={id:e.id,url:"",status:"skipped"};continue}try{let D=new URL(b);if(D.protocol!=="http:"&&D.protocol!=="https:"){w[E]={id:e.id,url:b,status:"skipped"};continue}}catch{w[E]={id:e.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:e.id,url:b,status:j,httpStatus:P.status,reason:y?"bot-protected-or-head-disallowed":void 0}}catch(P){clearTimeout(v),w[E]={id:e.id,url:b,status:"dead",error:P.name==="AbortError"?"timeout":P.message}}}catch(D){w[E]={id:e.id,url:b,status:"dead",error:D.message}}}catch(b){w[E]={id:"?",url:"",status:"dead",error:b?.message||"unknown"}}}}let h=Math.min(a.length,p);await Promise.all(Array.from({length:h},()=>_()));for(let E of w)if(E.status==="reachable")l.push(E);else if(E.status==="dead")g.push(E);else r.push(E);return{reachable:l,dead:g,skipped:r,ok:g.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((l)=>f.has(l?.id)):t,a=await cg(p,{timeoutMs:6000,concurrency:4});if(!a.ok)process.stderr.write(`[greedysearch] ${a.dead.length} dead citation URL(s) detected
|
|
445
|
+
`);return a}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:a=[],questions:l=[],rounds:g=[],qualityScore:r=0,qualityThreshold:w=8.5,maxSources:$=8,requireCitations:_=!0,requireQuestions:h=!0}={}){let E=n.filter((T)=>T?.fetch?.ok||(T?.contentChars||0)>100||String(T?.content||"").length>100),e=t.filter((T)=>["official-docs","repo","maintainer-blog","academic"].includes(String(T?.sourceType||""))),b=Array.isArray(f?.claims)?f.claims:[],D=p?p.cited?.length||0:0,v=Zn(l),P=(l||[]).filter((T)=>!T.createdRound||T.reason==="Original research question"),R=Zn(P),y=(g||[]).length,j=Math.min(4,Math.max(2,Number($)||8)),I=y<=1?Math.min(2,j):j,F={roundsRun:g.length>=1,fetchedSources:E.length>=I,primarySources:e.length>=1,qualityScore:r>=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:!h||R.open===0};return{floorMet:Object.values(F).every(Boolean),checks:F,metrics:{fetchedOk:E.length,primarySources:e.length,claims:b.length,cited:D,gaps:a.length,openQuestions:v.open,closedQuestions:v.closed,totalQuestions:v.total,openRequiredQuestions:R.open,closedRequiredQuestions:R.closed,totalRequiredQuestions:R.total,qualityScore:r,minFetched:I}}}function Qf(t,n){let f=new Map;for(let p of n||[]){let a=m(p?.canonicalUrl||p?.finalUrl||p?.url);if(a&&p?.id)f.set(a,p.id)}return(t||[]).map((p,a)=>{let l=m(p?.finalUrl||p?.canonicalUrl||p?.url);return{...p,id:p?.id||f.get(l)||`F${a+1}`}})}function Ln(t){return[{id:"Q1",question:H(c(t),320),status:"open",reason:"Original research question",evidence:[],sourceIds:[]}]}function dg(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 a=H(c(n),320);if(!a)return null;let l=df(t,a);if(l)return l;let g={id:dg(t),question:a,status:"open",reason:H(f,240),createdRound:p,evidence:[],sourceIds:[]};return t.push(g),g}function Qt(t,n,{evidence:f="",sourceIds:p=[],round:a=null}={}){let l=t.find((g)=>g.id===n)||df(t,n);if(!l)return null;if(l.status="closed",l.closedRound=l.closedRound||a,f)l.evidence=lt([...l.evidence||[],f],4);if(Array.isArray(p))l.sourceIds=lt([...l.sourceIds||[],...p],8);return l}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 a=5,l=t.filter((w)=>w.status==="open"&&w.reason==="Discovered gap/follow-up");if(l.length>a){let w=l.sort(($,_)=>($.createdRound||0)-(_.createdRound||0)).slice(0,l.length-a);for(let $ of w)$.status="resolved",$.closedRound=n,$.evidence=lt([...$.evidence||[],"Auto-resolved to cap open-question ledger"],4)}let g=Array.isArray(p.answeredQuestions)?p.answeredQuestions:[];for(let w of g){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 r=Array.isArray(p.newQuestions)?p.newQuestions:[];for(let w of r)Wn(t,w,{reason:"Discovered gap/follow-up",round:n});return t}function qg(t,n){if(!Array.isArray(t)||t.length===0)return[];let f=["arxiv.org","semanticscholar.org","doi.org"],p=new Set,a=[];for(let l of t){let g=l?.canonicalUrl||l?.finalUrl||l?.url||"";if(!g)continue;let r="";try{r=new URL(g).hostname.toLowerCase().replace(/^www\./,"")}catch{continue}if(!f.some(($)=>r===$||r.endsWith(`.${$}`)))continue;if(n.has(g)||p.has(g))continue;p.add(g);let w=g.includes("/pdf/")?g.replace(/\/pdf\//,"/html/").replace(/\.pdf$/i,""):g;a.push({url:w,label:l?.title||l?.id||r})}return a.slice(0,2)}function Yn(t,n,f){if(!n?.answer||f?.ok!==!0)return t;let p=Array.isArray(n.claims)?n.claims:[],a=Array.isArray(f.cited)?f.cited:[];if(p.length===0||a.length===0)return t;for(let l of t){if(l.status==="closed")continue;let g=null,r=0;for(let w of p){let $=Kn(l.question||"",w.claim||"");if($>r)r=$,g=w}if(l.id==="Q1"||r>=0.18)Qt(t,l.id,{evidence:g?.claim||"Answered in final cited synthesis",sourceIds:Array.isArray(g?.sourceIds)?g.sourceIds:a.slice(0,4)})}return t}function sg(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 mn(t,n="None recorded."){let f=lt(t);return f.length?f.map((p)=>`- ${p}`).join(`
|
|
448
|
+
`):n}function ug(t,{query:n,rounds:f,sources:p,fetchedSources:a,citationAudit:l,citationUrls:g,floor:r,manifest:w}){let $=(a||[]).filter((D)=>D?.contentChars>100||D?.fetch?.ok),_=(p||[]).filter((D)=>["official-docs","repo","maintainer-blog","academic"].includes(String(D?.sourceType||""))),h=new Set(l?.cited||[]),E=(p||[]).filter((D)=>h.has(D?.id)),e=[`# 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){e.push("### Cited sources","");for(let D of E){let v=D.canonicalUrl||D.finalUrl||D.url||"",P=D.fetch?.ok?"✓":"✗";e.push(`- **${D.id}:** [${D.title||v}](${v}) (${D.sourceType||"unknown"}, fetched: ${P})`)}e.push("")}if(g&&(g.reachable.length>0||g.dead.length>0)){if(e.push("## URL reachability",""),g.dead.length>0){e.push(""),e.push("**Dead links:**");for(let D of g.dead)e.push(`- ${D.id}: ${D.url} (${D.httpStatus||D.error||"unknown"})`)}if(g.reachable.length>0)e.push(""),e.push(`**Reachable:** ${g.reachable.length}/${g.reachable.length+g.dead.length}`);e.push("")}let b=!l?"NOT CHECKED":l.ok&&(g?.ok??!0)?"PASS":l.ok===!1?"FAIL (missing citations)":"FAIL (dead links)";if(e.push("## Verification","",`- **Citations:** ${l?.ok?"PASS":`FAIL — missing: ${(l?.missing||[]).join(", ")}`}`,`- **URL reachability:** ${g?g.ok?"PASS":`FAIL — ${g.dead.length} dead`:"SKIPPED"}`,`- **Floor:** ${r?.floorMet?"PASS":"PARTIAL"}`,`- **Overall:** ${b}`,""),r?.checks){e.push("## Floor checks","");for(let[D,v]of Object.entries(r.checks))e.push(`- [${v?"x":" "}] ${D}`);e.push("")}J(Y(t,"provenance.md"),e.join(`
|
|
449
|
+
`),"utf8")}async function In({query:t,rounds:n,sources:f,fetchedSources:p,evidenceItems:a=[],synthesis:l,citationAudit:g,floor:r,manifest:w,allGaps:$=[],questions:_=[],citationUrls:h=null,outDir:E=null}){let e=new Date().toISOString().replaceAll(/[:.]/g,"-").slice(0,19),b=E||Y(Og,`${e}_${ig(t)}`),D=Y(b,"reports"),v=Y(b,"sources"),P=Y(b,"data");Fn(D,{recursive:!0}),Fn(v,{recursive:!0}),Fn(P,{recursive:!0});let R=await Vn(p,v),y=lt([...$,...n.flatMap((j)=>j.gaps||[])]);J(Y(b,"STATUS.md"),[r.floorMet?"STATUS: DONE":"STATUS: PARTIAL","",`Query: ${t}`,`Stop reason: ${w.terminationReason||"max_rounds"}`,"","## Deterministic floor checks",...Object.entries(r.checks).map(([j,I])=>`- [${I?"x":" "}] ${j}`),"","## Questions",sg(_),"","## Open gaps",mn(y),""].join(`
|
|
450
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(
|
|
452
|
-
`),"utf8"),J(Y(D,"EVIDENCE.md"),["# Extracted evidence","",...
|
|
451
|
+
`),"utf8"),J(Y(D,"SUMMARY.md"),String(l.answer||""),"utf8"),J(Y(D,"CLAIMS.md"),["# Key claims","",...Array.isArray(l.claims)&&l.claims.length?l.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","",...a.length?a.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(`
|
|
453
453
|
`)):["No goal-based evidence was extracted."],""].join(`
|
|
454
|
-
`),"utf8"),J(Y(D,"GAPS.md"),["# Gaps and caveats","","## Caveats",
|
|
455
|
-
`),"utf8"),J(Y(P,"manifest.json"),JSON.stringify({...w,floor:
|
|
456
|
-
`),"utf8");try{
|
|
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
|
|
454
|
+
`),"utf8"),J(Y(D,"GAPS.md"),["# Gaps and caveats","","## Caveats",mn(l.caveats||[]),"","## Research gaps",mn(y),""].join(`
|
|
455
|
+
`),"utf8"),J(Y(P,"manifest.json"),JSON.stringify({...w,floor:r,citationAudit:g},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(a,null,2),"utf8"),J(Y(v,"index.md"),["# Source index","",...R.map((j)=>{let I=j.title||j.url,F=j.finalUrl||j.url,T=j.contentPath?` — ${j.contentPath}`:"";return`- ${j.id||"?"}: [${I}](${F})${T}`}),""].join(`
|
|
456
|
+
`),"utf8");try{ug(b,{query:t,rounds:n,sources:f,fetchedSources:p,citationAudit:g,citationUrls:h,floor:r,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 F0({query:t,breadth:n,iterations:f,maxSources:p,locale:a=null,short:l=!1,qualityThreshold:g=8.5,writeBundle:r=process.env.GREEDY_RESEARCH_BUNDLE!=="0",researchOutDir:w=null}={}){let $=Ag({breadth:n,iterations:f,maxSources:p}),_=n!==void 0&&n!==null,h=f!==void 0&&f!==null;if(!_&&!h)try{let O=await pf(t);if(process.stderr.write(`[greedysearch] Complexity: ${O.complexity} (${O.reasoning})
|
|
458
458
|
`),O.complexity==="simple")return process.stderr.write(`[greedysearch] Simple query detected — using fast single-pass path
|
|
459
|
-
`),Jf({query:t,locale:
|
|
460
|
-
`)}let
|
|
459
|
+
`),Jf({query:t,locale:a,maxSources:Math.min(p??5,5),qualityThreshold:g,writeBundle:r,researchOutDir:w});if(!_)$.breadth=O.suggestedBreadth;if(!h)$.iterations=O.suggestedIterations}catch(O){process.stderr.write(`[greedysearch] Scale classification failed, using defaults: ${O.message}
|
|
460
|
+
`)}let e=[],b=[],D=[],v=Ln(t),P=null,R=[],y=[],j=[],I=new Set,F=new Set,T=new Set,k=[],G="max_rounds",ht=new Date().toISOString(),d=Date.now(),wt=0,N=0,o=0,rt=[],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 ${g}, engines ${kt.join(",")}, synthesizer gemini
|
|
461
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(
|
|
463
|
-
`);let i=
|
|
464
|
-
`);return i}if(C.type==="fetchUrl"){let i=!
|
|
465
|
-
`);return i}return!1}).slice(0,s),Bn=
|
|
462
|
+
`),!P)try{let C=await X(Mg(t,s,b,D,[...T]),{timeoutMs:120000}),i=Zg(C,s);if(O===0)i.unshift({type:"search",query:t,researchGoal:"Original user query"});i=await Jg(i,T),P=i}catch(C){process.stderr.write(`[greedysearch] Action planning failed, using fallback queries: ${C.message}
|
|
463
|
+
`);let i=kg(null,t,s,{includeOriginal:O===0,exclude:F});P=Kg(i)}let Q=(P||[]).filter((C)=>{if(C.type==="search"){let i=!zf(C.query,F,{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=!T.has(C.url);if(!i)process.stderr.write(`[greedysearch] Novelty gate rejected fetch: ${C.url}
|
|
465
|
+
`);return i}return!1}).slice(0,s),Bn=qg(R,T);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
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
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
|
|
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=
|
|
470
|
-
`);let C=new Set,i=(tt)=>{try{return
|
|
468
|
+
`),Z.startAction(i.type,(i.query||i.url||"").slice(0,60));let W=await Wg(i,{locale:a,short:l,usedQueries:F,usedUrls:T,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)rt.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=Qg([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 m(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 Tg(W,Math.min(zt,W.length),8000,Math.min(3,zt||1));y=xf([...y,...fp]),R=Gt(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
471
|
`),process.stderr.write(`PROGRESS:research:round-${L}:learning
|
|
472
|
-
`);let Yt=await
|
|
472
|
+
`);let Yt=await Bg({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:Gg(C.result)})),evidenceItems:j}),bt={evidence:Yt.evidence,error:Yt.evidenceError};if(bt.error)process.stderr.write(`[greedysearch] Evidence extraction failed: ${bt.error}
|
|
473
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=
|
|
475
|
-
`),Z.endRound(),L<$.iterations)Z.startRound(L+1);let
|
|
476
|
-
`),
|
|
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&&
|
|
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=lt([...b,...zn]),D=lt([...D,...ct]),Ut(v,{roundNumber:L,actions:[],learningPayload:Ct,gaps:ct}),e.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 V=L===$.iterations?{score:k.length>0?k[k.length-1]:5,coverage:{},knowledgeGaps:[],shouldContinue:!1,nextActions:[],terminationReason:null,evaluationError:""}:await Fg(t,e,b,D,k);k.push(V.score),D=lt([...D,...V.knowledgeGaps||[]]),Ut(v,{roundNumber:L,gaps:V.knowledgeGaps||[]});let Sn=Bt({sources:R,fetchedSources:y,gaps:D,questions:v,rounds:e,qualityScore:V.score,qualityThreshold:g,maxSources:$.maxSources,requireCitations:!1,requireQuestions:!1});if(process.stderr.write(`[greedysearch] Quality score round ${L}: ${V.score.toFixed(1)} (shouldContinue: ${V.shouldContinue}, floor: ${Sn.floorMet})
|
|
476
|
+
`),V.score>=g&&Sn.floorMet&&(!V.shouldContinue||V.terminationReason==="quality_threshold")){G=V.terminationReason||"quality_threshold",process.stderr.write(`[greedysearch] Research floor reached (score: ${V.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&&V.nextActions.length>0){let C=V.nextActions.map((W)=>Sf(W)).filter(Boolean);u=[...u,...C].slice(0,_t)}if(u.length<_t&&D.length>0){let C=Ig(D,t,F,_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
478
|
`)}P=u.length>=_t?u:null}process.stderr.write(`PROGRESS:research:final-report
|
|
479
|
-
`);let
|
|
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(
|
|
481
|
-
`),
|
|
482
|
-
`);try{let O=
|
|
483
|
-
`),
|
|
484
|
-
`);let Ot=kn(
|
|
485
|
-
`);try{Nt=await In({query:t,rounds:
|
|
486
|
-
`),Z.finish(),{query:t,_research:{mode:"iterative",breadth:$.breadth,iterations:$.iterations,maxSources:$.maxSources,rounds:
|
|
479
|
+
`);let A={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(Tn(t,e,R,v,j),{timeoutMs:180000}),L=Ht(O,{}),s=Array.isArray(L?.claims)&&L.claims.length>0;A={...A,...L,rawAnswer:O.answer||"",geminiSources:O.sources||[],synthesized:s}}catch(O){process.stderr.write(`[greedysearch] Final report failed: ${O.message}
|
|
481
|
+
`),A.error=O.message}if(!(A.synthesized===!0&&Array.isArray(A.claims)&&A.claims.length>0)&&j.length>0){process.stderr.write(`[greedysearch] Falling back to evidence-based synthesis (no per-round learnings).
|
|
482
|
+
`);try{let O=An(t,R,v,j),L=await X(O,{timeoutMs:180000}),s=Ht(L,{});A={...A,...s,rawAnswer:L.answer||A.answer||"",geminiSources:L.sources||A.geminiSources||[],synthesized:!0,synthesisMode:"evidence_fallback"}}catch(O){process.stderr.write(`[greedysearch] Evidence-based synthesis failed: ${O.message}
|
|
483
|
+
`),A.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(A.answer||"",R),Xn=await Hn(R,Ot);Yn(v,A,Ot);let Et=Bt({sources:R,fetchedSources:y,synthesis:A,citationAudit:Ot,gaps:D,questions:v,rounds:e,qualityScore:qf,qualityThreshold:g,maxSources:$.maxSources});if(Et.floorMet&&G==="max_rounds")G="done_floor_met";else if(!Et.floorMet&&G==="quality_threshold")G="max_rounds_floor_unmet";let on={startedAt:ht,finishedAt:q,durationMs:xt,engines:kt,synthesizer:"gemini",rounds:e.length,actionsRun:wt,searches:N,fetches:o,sourcesFetched:y.filter((O)=>O?.contentChars>100).length,engineFailures:rt,terminationReason:G,floorMet:Et.floorMet},Nt=null,Lt;if(r){process.stderr.write(`PROGRESS:research:bundle
|
|
485
|
+
`);try{Nt=await In({query:t,rounds:e,sources:R,fetchedSources:y,evidenceItems:j,synthesis:A,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 Vn(y)}}else Lt=await Vn(y);return process.stderr.write(`PROGRESS:research:done
|
|
486
|
+
`),Z.finish(),{query:t,_research:{mode:"iterative",breadth:$.breadth,iterations:$.iterations,maxSources:$.maxSources,rounds:e,learnings:b,gaps:D,evidence:j,questions:v,questionProgress:Zn(v),qualityHistory:k,terminationReason:G,qualityThreshold:g,floor:Et,bundle:Nt,manifest:on},_citationAudit:Ot,_citationUrls:Xn,_sources:R,_fetchedSources:Lt,_synthesis:A,_confidence:{sourcesCount:R.length,fetchedSourceSuccessRate:y.length>0?Number((y.filter((O)=>O.contentChars>100).length/y.length).toFixed(2)):0,agreementLevel:A.agreement?.level||"mixed",floorMet:Et.floorMet}}}function xf(t){let n=new Map;for(let g of t){let r=g?.id||m(g?.finalUrl||g?.url||"");if(!r)continue;let w=n.get(r);if(!w||(g.contentChars||0)>(w.contentChars||0))n.set(r,g)}let f=new Map;function p(g){let r=f.get(g);if(!r){let w=String(g.content||g.snippet||"");r={length:w.length,tokens:Jn(w.slice(0,4000))},f.set(g,r)}return r}function a(g,r){let w=0,$=g.size<=r.size?g:r,_=g.size<=r.size?r:g;for(let E of $)if(_.has(E))w++;let h=g.size+r.size-w;if(h===0)return 1;return w/h}let l=[];for(let g of n.values()){let r=p(g),w=l.findIndex(($)=>{let _=f.get($);if(r.length<400||_.length<400)return!1;return a(r.tokens,_.tokens)>=0.9});if(w===-1){l.push(g);continue}if((g.contentChars||0)>(l[w].contentChars||0))l[w]=g}return l}export{In as writeResearchBundle,ug as writeProvenanceSidecar,Sf as validateAction,Ut as updateQuestionLedger,Jn as tokenSet,F0 as runResearchMode,Hn as runCitationUrlCheck,Yn as reconcileQuestionsFromSynthesis,Kg as queriesToActions,Zg as parseActionPlan,kg as normalizeResearchQueries,Kn as jaccardSimilarity,zf as isDuplicateQuery,Zf as extractEvidenceFromSources,Bg as extractEvidenceAndLearnings,Ln as createQuestionLedger,Bt as computeResearchFloor,Ag as clampResearchOptions,cg as checkCitationUrls,An as buildSynthesisFromEvidencePrompt,Tn as buildFinalReportPrompt,Ig as buildFallbackQueriesFromGaps,og as buildEvidenceAndLearningPrompt,kn as auditCitations};
|