@duckmind/dm-darwin-x64 0.52.3 → 0.52.6
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 +0 -0
- package/extensions/.dm-extensions.json +6 -3
- package/extensions/greedysearch-dm/bin/gschrome.mjs +5 -7
- package/extensions/greedysearch-dm/bin/launch-visible.mjs +2 -4
- package/extensions/greedysearch-dm/bin/launch.mjs +11 -5
- package/extensions/greedysearch-dm/bin/search.mjs +122 -120
- package/extensions/greedysearch-dm/extractors/consensus.mjs +43 -43
- package/extensions/greedysearch-dm/extractors/gemini.mjs +44 -44
- package/extensions/greedysearch-dm/extractors/logically.mjs +41 -41
- package/extensions/greedysearch-dm/index.js +18 -18
- package/extensions/greedysearch-dm/src/search/browser-lifecycle.mjs +8 -9
- package/extensions/greedysearch-dm/src/search/chrome.mjs +25 -25
- package/extensions/greedysearch-dm/src/search/constants.mjs +8 -8
- package/extensions/greedysearch-dm/src/search/engines.mjs +9 -9
- package/extensions/greedysearch-dm/src/search/fetch-source.mjs +49 -49
- package/extensions/greedysearch-dm/src/search/launcher-paths.mjs +3 -0
- package/extensions/greedysearch-dm/src/search/partial-output.mjs +1 -0
- package/extensions/greedysearch-dm/src/search/port-pid.mjs +1 -0
- package/extensions/greedysearch-dm/src/search/recovery.mjs +1 -1
- package/extensions/greedysearch-dm/src/search/research.mjs +101 -101
- package/extensions/greedysearch-dm/src/search/synthesis-runner.mjs +11 -11
- package/extensions/greedysearch-dm/src/search/synthesis.mjs +10 -10
- package/extensions/greedysearch-dm/src/tools/greedy-search-handler.js +18 -18
- package/extensions/greedysearch-dm/src/tools/shared.js +9 -9
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{randomInt as
|
|
3
|
-
`)[0]?.slice(0,8);if(!
|
|
4
|
-
`)}return
|
|
2
|
+
import{randomInt as nf}from"node:crypto";import{spawn as ff}from"node:child_process";import{dirname as gf,join as uf}from"node:path";import{fileURLToPath as rf}from"node:url";import{basename as tf}from"node:path";function of(n=process.env,f=process.execPath){let g=n.GREEDY_SEARCH_NODE||n.NODE_BINARY||n.NODE;if(g?.trim())return g.trim();let u=tf(f||"").toLowerCase();if(u==="node"||u==="node.exe")return f;return"node"}var lf=gf(rf(import.meta.url)),bf=uf(lf,"..","bin","cdp.mjs");function w(n,f=30000){return E(n,null,f)}function E(n,f=null,g=30000){return new Promise((u,r)=>{let t=ff(of(),[bf,...n],{stdio:[f==null?"ignore":"pipe","pipe","pipe"]});if(f!=null)t.stdin.write(f),t.stdin.end();let o="",l="";t.stdout.on("data",(i)=>o+=i),t.stderr.on("data",(i)=>l+=i);let b=setTimeout(()=>{t.kill(),r(Error(`cdp timeout: ${n[0]}`))},g);t.on("close",(i)=>{if(clearTimeout(b),i===0)u(o.trim());else r(Error(l.trim()||`cdp exit ${i}`))})})}async function Wn(n){if(n)return n;let f=(await w(["list"])).split(`
|
|
3
|
+
`)[0]?.slice(0,8);if(!f)throw Error("No Chrome tabs found. Is Chrome running with --remote-debugging-port=9222?");let g=await w(["evalraw",f,"Target.createTarget",'{"url":"about:blank"}']),{targetId:u}=JSON.parse(g);await w(["list"]);let r=u.slice(0,8);try{await Xn(r)}catch(t){process.stderr.write(`[getOrOpenTab] stealth injection failed: ${t.message}
|
|
4
|
+
`)}return r}async function Xn(n){await w(["evalraw",n,"Page.addScriptToEvaluateOnNewDocument",JSON.stringify({source:`
|
|
5
5
|
(function() {
|
|
6
6
|
// ── Runtime.enable / CDP detection masking ──────────────
|
|
7
7
|
try { delete window.__REBROWSER_RUNTIME_ENABLE; } catch(_) {}
|
|
@@ -209,10 +209,10 @@ import{randomInt as Fn}from"node:crypto";import{spawn as En}from"node:child_proc
|
|
|
209
209
|
};
|
|
210
210
|
} catch(_) {}
|
|
211
211
|
})();
|
|
212
|
-
`})])}var
|
|
212
|
+
`})])}var d={postNav:800,postNavSlow:1200,postClick:300,postType:300,inputPoll:400,copyPoll:600,afterVerify:1500};function m(n){let f=n*0.4,g=nf(-Math.floor(f),Math.floor(f)+1);return Math.max(50,Math.round(n+g))}async function Qn(n,f,g=15000,u=500){let r=String.raw`
|
|
213
213
|
new Promise((resolve) => {
|
|
214
|
-
const _deadline = Date.now() + ${
|
|
215
|
-
const _baseInterval = ${
|
|
214
|
+
const _deadline = Date.now() + ${g};
|
|
215
|
+
const _baseInterval = ${u};
|
|
216
216
|
|
|
217
217
|
function _jitter(ms) {
|
|
218
218
|
return Math.max(50, ms + (Math.random() * ms * 0.4 - ms * 0.2));
|
|
@@ -220,7 +220,7 @@ import{randomInt as Fn}from"node:crypto";import{spawn as En}from"node:child_proc
|
|
|
220
220
|
|
|
221
221
|
function _poll() {
|
|
222
222
|
try {
|
|
223
|
-
if (document.querySelector('${
|
|
223
|
+
if (document.querySelector('${f}')) { resolve(true); return; }
|
|
224
224
|
if (Date.now() < _deadline) { setTimeout(_poll, _jitter(_baseInterval)); }
|
|
225
225
|
else { resolve(false); }
|
|
226
226
|
} catch(_) { resolve(false); }
|
|
@@ -228,33 +228,33 @@ import{randomInt as Fn}from"node:crypto";import{spawn as En}from"node:child_proc
|
|
|
228
228
|
|
|
229
229
|
_poll();
|
|
230
230
|
})
|
|
231
|
-
`;return await
|
|
232
|
-
`)}function
|
|
231
|
+
`;return await w(["eval",n,r],g+5000)==="true"}async function Jn(n){let f=n.indexOf("--stdin");if(f===-1)return n;let g=await new Promise((r)=>{let t="";process.stdin.setEncoding("utf8"),process.stdin.on("data",(o)=>t+=o),process.stdin.on("end",()=>r(t.trim()))}),u=[...n];return u[f]=g,u}function en(n){let f=n.includes("--short"),g=n.filter((l)=>l!=="--short"),u=g.indexOf("--tab"),r=u===-1?null:g[u+1];if(u!==-1)g=g.filter((l,b)=>b!==u&&b!==u+1);let t=g.indexOf("--locale"),o=t===-1?null:g[t+1];if(t!==-1)g=g.filter((l,b)=>b!==t&&b!==t+1);return{query:g.join(" "),tabPrefix:r,short:f,locale:o}}function jn(n,f){if(!n.length||n[0]==="--help")process.stderr.write(f),process.exit(1)}function Zn(n,f,g=300){if(!f||n.length<=g)return n;let u=n.slice(0,g),r=u.lastIndexOf(" ");return r>0?`${u.slice(0,r)}…`:`${u}…`}function qn(n){process.stdout.write(`${JSON.stringify(n,null,2)}
|
|
232
|
+
`)}function W(n,f,g=null){if(!n||typeof n!=="object")return;let u=g?` (+${Date.now()-g}ms)`:"";if(n.lastStage=f,!Array.isArray(n.stages))n.stages=[];n.stages.push({stage:f,at:Date.now()});let r=n.engine||"extractor";console.error(`[${r}] stage: ${f}${u}`)}function nn({engine:n,mode:f="headless",clipboardEmpty:g=null,fallbackUsed:u=null,blockedBy:r=null,verificationResult:t=null,inputReady:o=null,durationMs:l=null,lastStage:b=null,stages:i=null}={}){return{engine:n,mode:f,clipboardEmpty:g,fallbackUsed:u,blockedBy:r,verificationResult:t,inputReady:o,durationMs:l,lastStage:b,stages:i}}function Bn(n,f=null){if(f){let g=JSON.stringify({_envelope:f,error:n.message});process.stdout.write(`${g}
|
|
233
233
|
`)}process.stderr.write(`Error: ${n.message}
|
|
234
|
-
`),process.exit(1)}import{readFileSync as
|
|
235
|
-
[greedysearch] Available engines: ${Object.keys(
|
|
236
|
-
`);if(
|
|
237
|
-
`)}}}catch{}return
|
|
238
|
-
`,"utf8")}catch{}}
|
|
239
|
-
[greedysearch] Available synthesizers: ${
|
|
240
|
-
[greedysearch] Falling back to default: ${
|
|
241
|
-
`)}}}catch{}return
|
|
242
|
-
${
|
|
243
|
-
`}function
|
|
244
|
-
|
|
245
|
-
`)[0],10):null}catch{return null}}async function
|
|
246
|
-
`);return
|
|
247
|
-
${
|
|
248
|
-
`);return}
|
|
249
|
-
`),await
|
|
250
|
-
`),await
|
|
251
|
-
`);let
|
|
234
|
+
`),process.exit(1)}import{readFileSync as wg}from"node:fs";import{tmpdir as $g}from"node:os";import{spawn as Ef,execFileSync as mn,execSync as df}from"node:child_process";import{existsSync as L,readFileSync as F,renameSync as ng,unlinkSync as J,writeFileSync as I}from"node:fs";import $n from"node:http";import{platform as Tn,tmpdir as fg}from"node:os";import{basename as wf}from"node:path";function xn(n=process.env,f=process.execPath){let g=n.GREEDY_SEARCH_NODE||n.NODE_BINARY||n.NODE;if(g?.trim())return g.trim();let u=wf(f||"").toLowerCase();if(u==="node"||u==="node.exe")return f;return"node"}import{existsSync as Vn}from"node:fs";import{platform as $f}from"node:os";import{join as x}from"node:path";function X(n){let f=$f()==="win32",g=process.env.SystemRoot||"C:\\Windows",u={win32:{powershell:x(g,"System32","WindowsPowerShell","v1.0","powershell.exe"),powershell_ise:x(g,"System32","WindowsPowerShell","v1.0","powershell_ise.exe"),netstat:x(g,"System32","netstat.exe"),taskkill:x(g,"System32","taskkill.exe"),tasklist:x(g,"System32","tasklist.exe"),cmd:x(g,"System32","cmd.exe")},unix:{ps:"/usr/bin/ps",lsof:"/usr/bin/lsof",ss:"/usr/sbin/ss",grep:"/usr/bin/grep",kill:"/usr/bin/kill"}},r=f?u.win32:u.unix,t=n.toLowerCase();if(r[t]&&Vn(r[t]))return r[t];if(f&&t==="netstat"){let o=x(g,"Sysnative","netstat.exe");if(Vn(o))return o}return n}import{existsSync as p,mkdirSync as hf,readFileSync as _n,writeFileSync as Wf}from"node:fs";import{homedir as Xf}from"node:os";import{join as Hn}from"node:path";import{tmpdir as T}from"node:os";function Qf(n,f=9222){let g=Number.parseInt(String(n??""),10);return Number.isInteger(g)&&g>1024&&g<65535?g:f}var $=Qf(process.env.GREEDY_SEARCH_PORT,9222),Z=(process.env.GREEDY_SEARCH_PROFILE_DIR||process.env.CDP_PROFILE_DIR||`${T().replaceAll("\\","/")}/greedysearch-chrome-profile`).replaceAll("\\","/"),k=`${Z}/DevToolsActivePort`,Jf=`${T().replaceAll("\\","/")}/cdp-pages.json`,V=process.env.GREEDY_SEARCH_MODE_FILE||`${T().replaceAll("\\","/")}/greedysearch-chrome-mode`,sg=`${T().replaceAll("\\","/")}/greedysearch-visible-recovery.jsonl`,gn=Hn(Xf(),".dm"),Q=Hn(gn,"greedyconfig"),un=["perplexity","google","chatgpt"],rn="gemini";function ef(){try{if(p(Q)){let n=_n(Q,"utf8"),f=JSON.parse(n);if(Array.isArray(f.engines)&&f.engines.length>0&&f.engines.every((g)=>typeof g==="string")){let g=f.engines.filter((r)=>fn[r]),u=f.engines.filter((r)=>!fn[r]);if(u.length>0)process.stderr.write(`[greedysearch] Warning: ignoring unknown engine(s) in ${Q}: ${u.join(", ")}
|
|
235
|
+
[greedysearch] Available engines: ${Object.keys(fn).join(", ")}
|
|
236
|
+
`);if(g.length>0)return g;process.stderr.write(`[greedysearch] Warning: no valid engines in ${Q}, falling back to defaults: ${un.join(", ")}
|
|
237
|
+
`)}}}catch{}return un}function jf(){try{if(!p(gn))hf(gn,{recursive:!0});if(!p(Q))Wf(Q,JSON.stringify({engines:un,synthesizer:rn},null,2)+`
|
|
238
|
+
`,"utf8")}catch{}}jf();var cn=["gemini","chatgpt"];function Zf(){try{if(p(Q)){let n=_n(Q,"utf8"),f=JSON.parse(n);if(typeof f.synthesizer==="string"){let g=f.synthesizer.toLowerCase();if(cn.includes(g))return g;process.stderr.write(`[greedysearch] Warning: unknown synthesizer "${f.synthesizer}" in ${Q}
|
|
239
|
+
[greedysearch] Available synthesizers: ${cn.join(", ")}
|
|
240
|
+
[greedysearch] Falling back to default: ${rn}
|
|
241
|
+
`)}}}catch{}return rn}var fn={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"},Cg=ef();var Gg=Zf(),Rg=Math.max(1,Number.parseInt(process.env.GREEDY_FETCH_CONCURRENCY||"5",10)||5);process.env.CDP_PROFILE_DIR=Z;import{existsSync as Tg,mkdirSync as qf,readFileSync as kn,renameSync as Bf,unlinkSync as xf,writeFileSync as Kn}from"node:fs";import Vf from"node:http";import{platform as yn}from"node:os";import{dirname as cf}from"node:path";var Un=[9222,9223],_f=/^(0|false|no|off)$/i;function Hf(n){return[...new Set(n.filter(Boolean))]}function Nn(n,f="explicit"){let g=new URL(n),u=g.protocol==="wss:"?"wss:":"ws:",r=g.port?Number.parseInt(g.port,10):u==="wss:"?443:80;return{source:f,wsUrl:`${u}//${g.host}${g.pathname}${g.search}`,host:g.hostname,port:r,path:`${g.pathname}${g.search}`,httpUrl:`http://${g.hostname}:${r}`}}function vn(n=process.env){return![n.GREEDY_SEARCH_REUSE_EXISTING_BROWSER,n.DM_CUA_REUSE_EXISTING_BROWSER].some((f)=>f!==void 0&&_f.test(String(f)))}function tn(n){let f=Number.parseInt(String(n??""),10);return Number.isInteger(f)&&f>0&&f<65536?f:null}function Nf(n){if(!n)return null;let f=String(n).trim();if(!f)return null;let g=new URL(f.includes("://")?f:`http://${f}`),u=tn(g.port)||(g.protocol==="https:"?443:80);return{host:g.hostname,port:u,source:`env:${f}`}}function kf(n){if(!n)return[];return String(n).split(/[,\s]+/).map(tn).filter(Boolean)}function Kf({env:n=process.env,platformName:f=yn(),procVersionText:g=null}={}){if(f!=="linux")return!1;if(n.WSL_DISTRO_NAME||n.WSL_INTEROP)return!0;let u=g??(()=>{try{return kn("/proc/version","utf8")}catch{return""}})();return/microsoft|wsl/i.test(u)}function yf({env:n=process.env,platformName:f=yn(),procVersionText:g=null,resolvConfText:u=null}={}){let r=["localhost","127.0.0.1"];if(Kf({env:n,platformName:f,procVersionText:g})){let o=(u??(()=>{try{return kn("/etc/resolv.conf","utf8")}catch{return""}})()).match(/^\s*nameserver\s+([^\s#]+)/m);if(o)r.push(o[1]);r.push("host.docker.internal")}return Hf(r)}function Uf({env:n=process.env,hosts:f=yf({env:n}),autoPorts:g=Un,excludePorts:u=[]}={}){let r=[];for(let b of["GREEDY_SEARCH_CDP_WS_URL","DM_CUA_CDP_WS_URL","CDP_WS_URL"])if(n[b])r.push({wsUrl:n[b],source:`env:${b}`});for(let b of["GREEDY_SEARCH_CDP_URL","DM_CUA_CDP_URL","CDP_URL"])try{let i=Nf(n[b]);if(i)r.push(i)}catch{}for(let b of["GREEDY_SEARCH_EXISTING_CDP_PORT","DM_CUA_EXISTING_CDP_PORT","GREEDY_SEARCH_CDP_PORT","DM_CUA_CDP_PORT"]){let i=tn(n[b]);if(!i)continue;for(let h of f)r.push({host:h,port:i,source:`env:${b}`})}let t=kf(n.GREEDY_SEARCH_EXISTING_CDP_PORTS);for(let b of t)for(let i of f)r.push({host:i,port:b,source:"env:GREEDY_SEARCH_EXISTING_CDP_PORTS"});let o=new Set(u.filter(Boolean));if(vn(n))for(let b of g){if(o.has(b))continue;for(let i of f)r.push({host:i,port:b,source:"auto"})}let l=new Set;return r.filter((b)=>{let i=b.wsUrl||`${b.host}:${b.port}`;if(l.has(i))return!1;return l.add(i),!0})}async function vf(n,{timeoutMs:f=700}={}){if(n.wsUrl)return Nn(n.wsUrl,n.source);let g=n.host||"localhost",u=n.port;if(!u)return null;let r=await new Promise((t)=>{let o=Vf.get({host:g,port:u,path:"/json/version",timeout:f},(l)=>{let b="";l.setEncoding("utf8"),l.on("data",(i)=>b+=i),l.on("end",()=>t(l.statusCode===200?b:null))});o.on("error",()=>t(null)),o.setTimeout(f,()=>{o.destroy(),t(null)})});if(!r)return null;try{let t=JSON.parse(r);if(!t.webSocketDebuggerUrl)return null;let o=Nn(t.webSocketDebuggerUrl,n.source),l=o.path||new URL(t.webSocketDebuggerUrl).pathname;return{...o,host:g,port:u,httpUrl:`http://${g}:${u}`,wsUrl:`ws://${g}:${u}${l}`,path:l}}catch{return null}}async function Af(n={}){for(let f of Uf(n)){let g=await vf(f,n);if(g)return g}return null}function Mf(n){if(!n)throw Error("missing CDP endpoint");let f=new URL(n.wsUrl);return`${f.host}
|
|
242
|
+
${f.pathname}${f.search}
|
|
243
|
+
`}function Of(n,f){qf(cf(n),{recursive:!0});let g=`${n}.tmp-${process.pid}`;Kn(g,Mf(f),"utf8");try{xf(n)}catch{}Bf(g,n)}async function An({activePortFile:n,modeFile:f,env:g=process.env,excludePorts:u=[],autoPorts:r=Un}={}){if(!vn(g))return null;let t=await Af({env:g,excludePorts:u,autoPorts:r});if(!t)return null;if(Of(n,t),f)Kn(f,"existing","utf8");return t}import{existsSync as zf}from"node:fs";import{dirname as Yf,join as K}from"node:path";function Df(n){let f=new Set;return n.filter((g)=>{if(!g||f.has(g))return!1;return f.add(g),!0})}function sf({moduleDir:n,entrypoint:f=process.argv[1],env:g=process.env}={}){let u=f?Yf(f):null,r=g.GREEDY_SEARCH_EXTENSION_DIR?.trim()||null;return Df([r?K(r,"bin","launch.mjs"):null,n?K(n,"launch.mjs"):null,n?K(n,"..","bin","launch.mjs"):null,n?K(n,"..","..","bin","launch.mjs"):null,u?K(u,"launch.mjs"):null,u?K(u,"..","bin","launch.mjs"):null])}function Mn({moduleDir:n,entrypoint:f=process.argv[1],env:g=process.env,exists:u=zf}={}){let r=sf({moduleDir:n,entrypoint:f,env:g}),t=r.find((o)=>u(o));if(t)return t;throw Error(`GreedySearch launcher not found. Checked candidates:
|
|
244
|
+
${r.map((o)=>`- ${o}`).join(`
|
|
245
|
+
`)}`)}import{execFileSync as Cf}from"node:child_process";import{platform as Gf}from"node:os";function Rf(n,f){return Cf(X(n),f,{encoding:"utf8",stdio:["ignore","pipe","ignore"],timeout:5000})}function mf(n){let f=String(n||"").match(/\b(\d+)\b/);return f?Number.parseInt(f[1],10):null}function pf(n){return mf(n)}function Tf(n,f){for(let g of String(n||"").split(/\r?\n/)){if(!/\bLISTEN\b/i.test(g))continue;if(!g.trim().split(/\s+/).slice(0,6).some((t)=>t.endsWith(`:${f}`)))continue;let r=g.match(/\bpid=(\d+)\b/);if(r)return Number.parseInt(r[1],10)}return null}function af(n,f){for(let g of String(n||"").split(/\r?\n/)){let u=g.trim().split(/\s+/);if(u.length<5||u[0].toUpperCase()!=="TCP")continue;if(!u.at(-2)?.toUpperCase().startsWith("LISTEN"))continue;if(!u[1].endsWith(`:${f}`))continue;let t=Number.parseInt(u.at(-1),10);if(Number.isInteger(t)&&t>0)return t}return null}function on(n,f,g){try{return n(f,g)}catch{return null}}function a(n,{platformName:f=Gf(),run:g=Rf}={}){if(f==="win32")return af(on(g,"netstat",["-ano","-p","TCP"]),n);let u=on(g,"lsof",["-nP",`-iTCP:${n}`,"-sTCP:LISTEN","-t"]),r=pf(u);if(r)return r;if(f!=="linux")return null;return Tf(on(g,"ss",["-ltnp"]),n)}import{execFileSync as On,execSync as ru}from"node:child_process";import{existsSync as c,mkdirSync as Pf,readFileSync as y,unlinkSync as H,writeFileSync as N}from"node:fs";import{platform as Sf,tmpdir as sn}from"node:os";var z=sn().replaceAll("\\","/"),P=`${z}/greedysearch-chrome-metadata.json`,_=`${z}/greedysearch-chrome-launch.lock`,If=15000,A=`${z}/greedysearch-chrome.pid`,M=`${z}/greedysearch-chrome-mode`,U=`${z}/greedysearch-chrome-last-activity`;function O(n){if(!Number.isInteger(n)||n<=0)return!1;try{return process.kill(n,0),!0}catch{return!1}}function Lf(n){if(!O(n))return null;try{if(Sf()==="win32")return On(X("powershell"),["-NoProfile","-NonInteractive","-Command",`(Get-CimInstance Win32_Process -Filter "ProcessId = ${n}").CommandLine`],{encoding:"utf8",windowsHide:!0,timeout:5000}).trim()||null;return On(X("ps"),["-p",String(n),"-o","command="],{encoding:"utf8",timeout:5000}).trim()||null}catch{return null}}function ln(n,f,g=$){if(!n)return!1;let u=(o)=>String(o||"").replaceAll("\\","/").toLowerCase(),r=u(n),t=u(f);return r.includes(t)&&r.includes(`--remote-debugging-port=${g}`)&&!r.includes("--type=")}function zn(n,f,g=$){return ln(Lf(n),f,g)}function Ff(n=$){return a(n)}function Y(){try{if(c(P)){let n=y(P,"utf8"),f=JSON.parse(n);if(f&&typeof f.tempDir==="string"&&typeof f.debugPort==="number")return{browserPid:Number.isInteger(f.browserPid)?f.browserPid:void 0,debugPort:f.debugPort,tempDir:f.tempDir,clientPids:Array.isArray(f.clientPids)?f.clientPids.filter((g)=>Number.isInteger(g)&&g>0):[],sessionMode:f.sessionMode==="visible"?"visible":"headless",lastActivity:Number.isFinite(f.lastActivity)?f.lastActivity:0,launchedAt:Number.isFinite(f.launchedAt)?f.launchedAt:0}}}catch{}try{if(!(c(A)||c(M)||c(U)))return null;let f=c(A)?Number.parseInt(y(A,"utf8").trim(),10)||void 0:void 0,g=c(M)?y(M,"utf8").trim()==="visible"?"visible":"headless":"headless",u=c(U)?Number.parseInt(y(U,"utf8").trim(),10)||0:0;return{browserPid:f,debugPort:$,tempDir:Z,clientPids:f?[f]:[],sessionMode:g,lastActivity:u,launchedAt:0}}catch{return null}}function S(n){try{N(P,JSON.stringify({browserPid:n.browserPid,debugPort:n.debugPort,tempDir:n.tempDir,clientPids:[...new Set(n.clientPids.filter((f)=>f>0))],sessionMode:n.sessionMode,lastActivity:n.lastActivity,launchedAt:n.launchedAt},null,2),"utf8")}catch{}try{if(n.browserPid)N(A,String(n.browserPid),"utf8")}catch{}try{N(M,n.sessionMode,"utf8")}catch{}try{N(U,String(n.lastActivity),"utf8")}catch{}}function Yn(){try{H(P)}catch{}try{H(A)}catch{}try{H(M)}catch{}try{H(U)}catch{}}function Cn(n){if(!n)return n;let f={...n,clientPids:[...new Set([...n.clientPids,process.pid].filter((g)=>O(g)||g===process.pid))]};return S(f),f}function bn(n){let f=Date.now();try{if(n)S({...n,lastActivity:f});else N(U,String(f),"utf8")}catch{}}var wu=Number.parseInt(process.env.GREEDY_SEARCH_IDLE_TIMEOUT_MINUTES||"5",10)||5;var Dn=!1;function Gn(){if(Dn)return;Dn=!0;let n=Y();if(!n)return;if(n.browserPid){if(!O(n.browserPid)){Yn();return}if(!zn(n.browserPid,n.tempDir,n.debugPort))Yn();else S({...n,clientPids:n.clientPids.filter((r)=>O(r))})}let f=Ff();if(f&&f!==n.browserPid)if(zn(f,Z,$))S({browserPid:f,debugPort:$,tempDir:Z,clientPids:[f],sessionMode:n.sessionMode,lastActivity:Date.now(),launchedAt:Date.now()});else return}function Rn(){Pf(sn(),{recursive:!0});try{let n=JSON.stringify({pid:process.pid,ts:Date.now()});return N(_,n,{encoding:"utf8",flag:"wx"}),{acquired:!0,release:()=>{try{let f=y(_,"utf8");if(JSON.parse(f).pid===process.pid)H(_)}catch{}}}}catch(n){if(n?.code!=="EEXIST")return{acquired:!1,release:()=>{}}}try{let n=y(_,"utf8"),f=JSON.parse(n),g=Date.now()-(f.ts||0);if(!O(f.pid)||g>If){try{H(_)}catch{}try{let r=JSON.stringify({pid:process.pid,ts:Date.now()});return N(_,r,{encoding:"utf8",flag:"wx"}),{acquired:!0,release:()=>{try{H(_)}catch{}}}}catch{return{acquired:!1,release:()=>{}}}}}catch{}return{acquired:!1,release:()=>{}}}var gg=import.meta.dirname||new URL(".",import.meta.url).pathname.replace(/^\/([A-Z]:)/,"$1"),an=fg().replaceAll("\\","/"),D=`${an}/greedysearch-chrome.pid`,s=`${an}/greedysearch-chrome-last-activity`,ug=Number.parseInt(process.env.GREEDY_SEARCH_IDLE_TIMEOUT_MINUTES||"5",10)||5,rg=Number.parseInt(process.env.GREEDY_SEARCH_VISIBLE_IDLE_TIMEOUT_MINUTES||"60",10)||60;function tg(n,f=$){let g=String(n||"").toLowerCase();if(!g.includes(`--remote-debugging-port=${f}`)||g.includes("--type="))return null;return g.includes("--headless")}function Pn(){try{let n=hn(),f=n?Sn(n):null,g=tg(f);if(g!==null){try{I(V,g?"headless":"visible","utf8")}catch{}return g}}catch{}try{if(!L(V))return!0;return F(V,"utf8").trim()==="headless"}catch{return!0}}function og(){try{I(s,String(Date.now()),"utf8")}catch{}try{let n=Y();if(n)bn(n)}catch{}}function Sn(n){try{if(Tn()==="win32")return mn(X("powershell"),["-NoProfile","-NonInteractive","-Command",`(Get-CimInstance Win32_Process -Filter "ProcessId = ${n}").CommandLine`],{encoding:"utf8",windowsHide:!0,timeout:5000}).trim()||null;return mn(X("ps"),["-p",String(n),"-o","command="],{encoding:"utf8",timeout:5000}).trim()||null}catch{return null}}function hn(){return a($)}function In(){let n=[hn()];if(L(D))n.push(Number.parseInt(F(D,"utf8").trim(),10)||null);for(let f of n){if(!f)continue;if(ln(Sn(f),Z,$))return f}return null}async function lg(n=1500){let f=In();if(!f)return!1;try{let u=await new Promise((t,o)=>{let l=$n.get(`http://localhost:${$}/json/version`,(b)=>{let i="";b.on("data",(h)=>i+=h),b.on("end",()=>{try{t(JSON.parse(i))}catch{o(Error("bad JSON"))}})});l.on("error",o),l.setTimeout(1000,()=>{l.destroy(),o(Error("timeout"))})}),r=new globalThis.WebSocket(u.webSocketDebuggerUrl);await new Promise((t)=>{r.onopen=()=>{r.send(JSON.stringify({id:1,method:"Browser.close"})),setTimeout(()=>{r.close(),t()},200)},r.onerror=()=>t(),setTimeout(t,1000)})}catch{}let g=Date.now()+n;while(Date.now()<g){let u=hn();if(!u)return!0;if(u!==f)return!0;await new Promise((r)=>setTimeout(r,150))}return bg()}function bg(){try{let n=In();if(!n)return!1;if(Tn()==="win32")df(`${X("taskkill")} /F /PID ${n}`,{stdio:"ignore"});else process.kill(n,"SIGKILL");return!0}catch{return!1}}async function Ln(){if(!await v(500)){try{J(D)}catch{}try{J(s)}catch{}try{J(V)}catch{}return!1}let f=await lg(1500);try{J(D)}catch{}try{J(s)}catch{}try{J(V)}catch{}if(f)process.stderr.write(`[greedysearch] Killed Chrome on port ${$}.
|
|
246
|
+
`);return f}var pn=Ln;async function ig(){let f=Pn()?ug:rg;if(f<=0)return!1;if(!L(s))return og(),!1;try{let g=Number.parseInt(F(s,"utf8").trim(),10);if(!g)return!1;if((Date.now()-g)/60000>=f)return Ln()}catch{}return!1}function v(n=3000){return new Promise((f)=>{let g=$n.get(`http://localhost:${$}/json/version`,(u)=>{u.resume(),f(u.statusCode===200)});g.on("error",()=>f(!1)),g.setTimeout(n,()=>{g.destroy(),f(!1)})})}async function wn(){let n=`${k}.lock`,f=`${k}.tmp`,g=5000,u=1000,r=await new Promise((t)=>{let o=Date.now(),l=()=>{try{let b=JSON.stringify({pid:process.pid,ts:Date.now()});I(n,b,{encoding:"utf8",flag:"wx"}),t(!0)}catch(b){if(b?.code!=="EEXIST"){if(Date.now()-o<1000)setTimeout(l,50);else t(!1);return}try{let i=F(n,"utf8").trim(),h=i.startsWith("{")?JSON.parse(i):{ts:Number(i)},e=Number(h?.ts)||0;if(e>0&&Date.now()-e>5000)try{J(n)}catch{}if(Date.now()-o<1000)setTimeout(l,50);else t(!1)}catch{if(Date.now()-o<1000)setTimeout(l,50);else t(!1)}}};l()});try{let t=await new Promise((i,h)=>{let e=$n.get(`http://localhost:${$}/json/version`,(B)=>{let C="";B.on("data",(G)=>C+=G),B.on("end",()=>i(C))});e.on("error",h),e.setTimeout(3000,()=>{e.destroy(),h(Error("timeout"))})}),{webSocketDebuggerUrl:o}=JSON.parse(t),l=new URL(o),b=`${l.pathname}${l.search}`;if(r){I(f,`localhost:${$}
|
|
247
|
+
${b}`,"utf8");try{J(k)}catch{}ng(f,k)}}catch{}finally{if(r)try{J(n)}catch{}}}async function Fn(){let n=L(D)||!!Y(),f=await An({activePortFile:k,modeFile:V,excludePorts:n?[$]:[]});if(f){process.stderr.write(`[greedysearch] Reusing existing browser CDP endpoint ${f.httpUrl} (${f.source}).
|
|
248
|
+
`);return}Gn();let g=await ig(),u=g?!1:await v();if(!u&&!g)await new Promise((l)=>setTimeout(l,500)),u=await v();let r=!1;if(u){let l=Pn(),b=process.env.GREEDY_SEARCH_VISIBLE==="1";if(!b&&!l)process.stderr.write(`[greedysearch] Visible Chrome detected — switching to headless mode...
|
|
249
|
+
`),await pn(),await new Promise((i)=>setTimeout(i,1000)),r=!0;else if(b&&l)process.stderr.write(`[greedysearch] Headless Chrome detected — switching to visible mode...
|
|
250
|
+
`),await pn(),await new Promise((i)=>setTimeout(i,1000)),r=!0}if(r?!1:await v()){await wn();try{let l=Y();if(l)bn(l),Cn(l)}catch{}return}let o=Rn();if(!o.acquired){let l=Date.now()+15000;while(Date.now()<l)if(await new Promise((b)=>setTimeout(b,250)),await v(1000)){await wn();return}throw Error(`Timed out waiting for another GreedySearch launcher on port ${$}`)}try{if(await v(1000)){await wn();return}process.stderr.write(`GreedySearch Chrome not running on port ${$} — auto-launching...
|
|
251
|
+
`);let b=[Mn({moduleDir:gg,entrypoint:process.argv[1]})];if(process.env.GREEDY_SEARCH_VISIBLE!=="1")b.push("--headless");await new Promise((i,h)=>{Ef(xn(),b,{stdio:["ignore",process.stderr,process.stderr]}).on("close",(B)=>B===0?i():h(Error("launch.mjs failed")))})}finally{o.release()}}var hg="https://logically.app/research-assistant/",q={input:'.chat-control div.ProseMirror[contenteditable="true"][role="textbox"]',submitButton:'.chat-control button[class*="MuiButton-black"]',answerContainer:"#last-message .chat-content",citationSpan:"#last-message .chat-content span[title]"};async function Wg(n){return w(["eval",n,`(() => {
|
|
252
252
|
const buttons = Array.from(document.querySelectorAll('button'));
|
|
253
253
|
const create = buttons.find((b) => (b.innerText || '').trim() === 'Create');
|
|
254
254
|
if (!create) return 'missing';
|
|
255
255
|
create.click();
|
|
256
256
|
return 'clicked';
|
|
257
|
-
})()`],5000).catch(()=>"error")}async function
|
|
257
|
+
})()`],5000).catch(()=>"error")}async function Xg(n){return await w(["eval",n,`(() => {
|
|
258
258
|
const url = document.location.href || '';
|
|
259
259
|
if (url.includes('/login') || url.includes('/signup') || url.includes('/sign-up')) return true;
|
|
260
260
|
const modalText = Array.from(document.querySelectorAll('[role="dialog"], .MuiModal-root'))
|
|
@@ -262,8 +262,8 @@ ${l}`,"utf8");try{j(N)}catch{}Dr(r,N)}}catch{}finally{if(t)try{j(n)}catch{}}}asy
|
|
|
262
262
|
.join('
|
|
263
263
|
');
|
|
264
264
|
return /create a free account|continue with google|have an account[?] log in|log in|sign up/i.test(modalText);
|
|
265
|
-
})()`],5000).catch(()=>"false")==="true"}async function
|
|
266
|
-
const inputs = Array.from(document.querySelectorAll('${
|
|
265
|
+
})()`],5000).catch(()=>"false")==="true"}async function Qg(n){try{await w(["list"]);let f=`${$g().replaceAll("\\\\","/")}/cdp-pages.json`,u=JSON.parse(wg(f,"utf8")).find((r)=>r.targetId?.startsWith(n))?.targetId;if(u)await w(["browse",n,"Target.activateTarget",JSON.stringify({targetId:u})]).catch(()=>null),await new Promise((r)=>setTimeout(r,250))}catch{}}async function Jg(n,f){await Qg(n);let g=await w(["eval",n,`(() => {
|
|
266
|
+
const inputs = Array.from(document.querySelectorAll('${q.input}'));
|
|
267
267
|
const input = inputs.find((el) => {
|
|
268
268
|
const r = el.getBoundingClientRect();
|
|
269
269
|
return r.width > 20 && r.height > 5;
|
|
@@ -272,14 +272,14 @@ ${l}`,"utf8");try{j(N)}catch{}Dr(r,N)}}catch{}finally{if(t)try{j(n)}catch{}}}asy
|
|
|
272
272
|
input.scrollIntoView({ block: 'center', inline: 'center' });
|
|
273
273
|
const r = input.getBoundingClientRect();
|
|
274
274
|
return JSON.stringify({ x: Math.round(r.left + Math.min(80, r.width / 2)), y: Math.round(r.top + r.height / 2) });
|
|
275
|
-
})()`]);if(!
|
|
275
|
+
})()`]);if(!g)throw Error("Logically visible input not found");let u=JSON.parse(g);if(await w(["click",n,q.input]).catch(()=>null),await new Promise((t)=>setTimeout(t,m(120))),await w(["clickxy",n,String(u.x),String(u.y)]),await new Promise((t)=>setTimeout(t,m(d.postClick))),await E(["type",n,"--stdin"],f),await new Promise((t)=>setTimeout(t,m(d.postType))),await w(["eval",n,`Array.from(document.querySelectorAll('${q.input}')).some((el) => (el.innerText || '').length >= ${Math.floor(f.length*0.8)})`])!=="true")throw Error("Logically input did not accept text — input verification failed")}async function eg(n,f=90000){let g=String.raw`
|
|
276
276
|
new Promise((resolve, reject) => {
|
|
277
|
-
const deadline = Date.now() + ${
|
|
277
|
+
const deadline = Date.now() + ${f};
|
|
278
278
|
let last = '';
|
|
279
279
|
let stable = 0;
|
|
280
280
|
function poll() {
|
|
281
281
|
try {
|
|
282
|
-
const answer = document.querySelector('${
|
|
282
|
+
const answer = document.querySelector('${q.answerContainer}');
|
|
283
283
|
const text = (answer?.innerText || '').trim();
|
|
284
284
|
const body = document.body.innerText || '';
|
|
285
285
|
const stillGenerating = /Generating answer|Thinking\.\.\.|Searching the internet|Discovered \d+/.test(body) && text.length < 200;
|
|
@@ -289,12 +289,12 @@ ${l}`,"utf8");try{j(N)}catch{}Dr(r,N)}}catch{}finally{if(t)try{j(n)}catch{}}}asy
|
|
|
289
289
|
if (stable >= 3) { resolve(text.length); return; }
|
|
290
290
|
}
|
|
291
291
|
if (Date.now() < deadline) setTimeout(poll, 700 + Math.random() * 250);
|
|
292
|
-
else reject(new Error('Logically answer did not stabilise within ${
|
|
292
|
+
else reject(new Error('Logically answer did not stabilise within ${f}ms'));
|
|
293
293
|
} catch (e) { reject(e); }
|
|
294
294
|
}
|
|
295
295
|
poll();
|
|
296
|
-
})`;return
|
|
297
|
-
const el = document.querySelector('${
|
|
296
|
+
})`;return w(["eval",n,g],f+1e4)}async function jg(n){let f=`(() => {
|
|
297
|
+
const el = document.querySelector('${q.answerContainer}');
|
|
298
298
|
if (!el) return JSON.stringify({ answer: '', answerHtml: '' });
|
|
299
299
|
const clone = el.cloneNode(true);
|
|
300
300
|
clone.querySelectorAll('svg').forEach((n) => n.remove());
|
|
@@ -305,7 +305,7 @@ ${l}`,"utf8");try{j(N)}catch{}Dr(r,N)}}catch{}finally{if(t)try{j(n)}catch{}}}asy
|
|
|
305
305
|
answer: (el.innerText || '').trim(),
|
|
306
306
|
answerHtml: clone.innerHTML,
|
|
307
307
|
});
|
|
308
|
-
})()`;return JSON.parse(await
|
|
308
|
+
})()`;return JSON.parse(await w(["eval",n,f],1e4))}async function Zg(n){let f=String.raw`
|
|
309
309
|
(async () => {
|
|
310
310
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
311
311
|
|
|
@@ -445,10 +445,10 @@ ${l}`,"utf8");try{j(N)}catch{}Dr(r,N)}}catch{}finally{if(t)try{j(n)}catch{}}}asy
|
|
|
445
445
|
webCaptured: webSources.length,
|
|
446
446
|
},
|
|
447
447
|
});
|
|
448
|
-
})()`,
|
|
448
|
+
})()`,g=await w(["eval",n,f],20000);return JSON.parse(g)}async function qg(n){let f=String.raw`
|
|
449
449
|
(async () => {
|
|
450
450
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
451
|
-
const answer = document.querySelector('${
|
|
451
|
+
const answer = document.querySelector('${q.answerContainer}');
|
|
452
452
|
if (!answer) return JSON.stringify([]);
|
|
453
453
|
|
|
454
454
|
function parseUrlFromId(id) {
|
|
@@ -549,5 +549,5 @@ ${l}`,"utf8");try{j(N)}catch{}Dr(r,N)}}catch{}finally{if(t)try{j(n)}catch{}}}asy
|
|
|
549
549
|
}
|
|
550
550
|
}
|
|
551
551
|
return JSON.stringify(sources);
|
|
552
|
-
})()`,
|
|
553
|
-
`;async function
|
|
552
|
+
})()`,g=await w(["eval",n,f],45000);return JSON.parse(g)}var Bg=`Usage: node extractors/logically.mjs "<query>" [--tab <prefix>]
|
|
553
|
+
`;async function xg(){let n=await Jn(process.argv.slice(2));jn(n,Bg);let{query:f,tabPrefix:g,short:u}=en(n),r=Date.now(),o={engine:"logically",mode:process.env.GREEDY_SEARCH_VISIBLE==="1"?"visible":"headless",clipboardEmpty:null,fallbackUsed:null,blockedBy:null,verificationResult:null,inputReady:null};try{if(process.env.GREEDY_SEARCH_VISIBLE!=="1"&&process.env.GREEDY_SEARCH_ALWAYS_VISIBLE!=="1")process.env.GREEDY_SEARCH_HEADLESS="1";if(await Fn(),!g)await w(["list"]);let l=await Wn(g),b=await w(["eval",l,"document.location.href"]).catch(()=>""),i=!1;try{let j=new URL(b).hostname.toLowerCase();i=j==="logically.app"||j.endsWith(".logically.app")}catch{}if(!i)W(o,"nav",r),await w(["nav",l,hg],25000),await new Promise((j)=>setTimeout(j,900));W(o,"new-chat",r),await Wg(l),await new Promise((j)=>setTimeout(j,700)),W(o,"input-wait",r);let h=await Qn(l,q.input,20000,400);if(o.inputReady=h,!h)throw Error("Logically input not found — page may not have loaded or is in unexpected state");if(W(o,"type-and-submit",r),await Jg(l,f),await w(["eval",l,`(() => { const btn = document.querySelector('${q.submitButton}'); if (!btn) return 'missing'; btn.click(); return 'clicked'; })()`])!=="clicked")throw Error("Logically submit button not found");if(await new Promise((j)=>setTimeout(j,1500)),await Xg(l))throw o.blockedBy="signin",o.verificationResult="needs-human",Error("Logically login required — please log in or create a free account in the visible browser window. Once signed in, cookies persist for future runs.");W(o,"answer-wait",r),await eg(l,90000),W(o,"extract-answer-html",r);let{answer:B,answerHtml:C}=await jg(l);if(!B)throw Error("No answer extracted — Logically may not have responded");W(o,"extract-inline-citations",r);let G=await qg(l);W(o,"extract-full-citations",r);let R=await Zg(l),En=R.sources?.length?R.sources:G,dn=await w(["eval",l,"document.location.href"]).catch(()=>"");o.durationMs=Date.now()-r,o.sourcePath=R.sources?.length?"citations-popover":"inline-citation-popovers",W(o,"done",r),qn({query:f,url:dn,answer:Zn(B,u),answerHtml:C,sources:En,inlineSources:G,citationSummary:R.summary,_envelope:nn(o)})}catch(l){o.durationMs=Date.now()-r,Bn(l,nn(o))}}xg();
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import{spawn as
|
|
2
|
-
`:`*Synthesized by ${
|
|
3
|
-
`)
|
|
4
|
-
`).trim()}for(let[
|
|
5
|
-
## ${
|
|
6
|
-
`).trim()}function
|
|
7
|
-
`).trim()}function
|
|
8
|
-
Sources:`);for(let
|
|
9
|
-
[greedysearch] Available engines: ${Object.keys(
|
|
10
|
-
`);if(
|
|
11
|
-
`)}}}catch{}return
|
|
12
|
-
`,"utf8")}catch{}}
|
|
13
|
-
[greedysearch] Available synthesizers: ${
|
|
1
|
+
import{spawn as L0}from"node:child_process";import{existsSync as R0,mkdirSync as _0,readFileSync as N0,writeFileSync as v0}from"node:fs";import{homedir as C0}from"node:os";import{dirname as F0,join as p}from"node:path";import{fileURLToPath as I0}from"node:url";import{Type as z}from"@sinclair/typebox";function L(J){return{bing:"Bing Copilot",google:"Google AI",gemini:"Gemini",copilot:"Copilot",perplexity:"Perplexity"}[J]??J.charAt(0).toUpperCase()+J.slice(1)}function u(J){if(!J)return"";if(J==="official-docs")return"official docs";return J.replace(/-/g," ")}function d(J){if(!J)return"Mixed";return J.charAt(0).toUpperCase()+J.slice(1)}function m(J){return String(J.displayUrl||J.canonicalUrl||J.url||"")}function W0(J){return String(J.title||J.domain||m(J)||"Untitled source")}function Z0(J){if(typeof J.engineCount==="number")return J.engineCount;return(Array.isArray(J.engines)?J.engines:[]).length}function q0(J){return new Map(J.map((X)=>[String(X.id||""),X]).filter(([X])=>X))}function c(J){let X=String(J.id||"?"),$=m(J),K=W0(J),B=String(J.domain||""),Q=Array.isArray(J.engines)?J.engines:[],W=Z0(J),V=u(String(J.sourceType||"")),q=J.fetch,Z=q?.ok?`fetched ${q.status||200}`:q?.attempted?"fetch failed":"";return`- ${[`${X} - [${K}](${$})`,B,V,Q.length?`cited by ${Q.map(L).join(", ")} (${W}/3)`:`${W}/3`,Z].filter(Boolean).join(" - ")}`}function l(J,X=[],$=6){if(!J.length)return[];let K=q0(J),B=X.map((Q)=>K.get(Q)).filter((Q)=>Boolean(Q));if(B.length>0)return B.slice(0,$);return J.slice(0,$)}function o(J,X,$,K=6){if(X.answer)J.push("## Answer"),J.push(String(X.answer)),J.push("");let B=X.agreement,Q=String(B?.summary||"").trim(),W=String(B?.level||"").trim();if(Q||W)J.push("## Consensus"),J.push(`- ${d(W)}${Q?` - ${Q}`:""}`),J.push("");let V=Array.isArray(X.differences)?X.differences:[];if(V.length>0){J.push("## Where Engines Differ");for(let k of V)J.push(`- ${k}`);J.push("")}let q=Array.isArray(X.caveats)?X.caveats:[];if(q.length>0){J.push("## Caveats");for(let k of q)J.push(`- ${k}`);J.push("")}let Z=Array.isArray(X.claims)?X.claims:[];if(Z.length>0){J.push("## Key Claims");for(let k of Z){let H=Array.isArray(k.sourceIds)?k.sourceIds:[],O=String(k.support||"moderate");J.push(`- ${String(k.claim||"")} [${O}${H.length?`; ${H.join(", ")}`:""}]`)}J.push("")}let M=Array.isArray(X.recommendedSources)?X.recommendedSources:[],b=l($,M,K);if(b.length>0){J.push("## Top Sources");for(let k of b)J.push(c(k));J.push("")}}function i(J,X){let $=[];if(J==="all")return Y0(X,$);return k0(X,$)}function Y0(J,X){let{_synthesis:$,_sources:K,_needsHumanVerification:B,_research:Q}=J;if(B){let W=Array.isArray(B.engines)?B.engines.join(", "):"one or more engines";X.push("## Manual verification required"),X.push(String(B.message||"Visible Chrome is open. Solve the verification challenge, then rerun the same search.")),X.push(`Engines: ${W}`),X.push("")}if($?.answer){if(Q?.mode==="iterative")z0(X,Q);o(X,$,K||[],6);let W=String($.synthesizedBy||"configured synthesizer");return X.push(Q?.mode==="iterative"?`*Research mode: iterative planning, source fetching, citation audit, and bundle output*
|
|
2
|
+
`:`*Synthesized by ${W} from multi-engine results and fetched sources*
|
|
3
|
+
`),X.join(`
|
|
4
|
+
`).trim()}for(let[W,V]of Object.entries(J)){if(W.startsWith("_"))continue;X.push(`
|
|
5
|
+
## ${L(W)}`),t(V,X,3)}return X.join(`
|
|
6
|
+
`).trim()}function z0(J,X){let $=X.floor,K=$?.metrics,B=X.bundle,Q=X.manifest;if(J.push("## Research Run"),J.push(`- Status: ${$?.floorMet?"floor met":"partial / floor unmet"}`),Q?.terminationReason)J.push(`- Stop reason: ${String(Q.terminationReason)}`);if(K)J.push(`- Evidence: ${K.fetchedOk||0} fetched sources, ${K.primarySources||0} primary/official, ${K.claims||0} claims, ${K.cited||0} citations`),J.push(`- Questions: ${K.closedQuestions||0}/${K.totalQuestions||0} closed${K.openQuestions?`, ${K.openQuestions} open`:""}`);if(B?.dir)J.push(`- Bundle: ${String(B.dir)}`);J.push("")}function k0(J,X){let $=J._needsHumanVerification;if($){let K=Array.isArray($.engines)?$.engines.join(", "):"this engine";X.push("## Manual verification required"),X.push(String($.message||"Visible Chrome is open. Solve the verification challenge, then rerun the same search.")),X.push(`Engines: ${K}`),X.push("")}return t(J,X,5),X.join(`
|
|
7
|
+
`).trim()}function t(J,X,$){if(J.error){X.push(`Error: ${J.error}`);return}if(J.answer)X.push(String(J.answer));let K=J.sources;if(Array.isArray(K)&&K.length>0){X.push(`
|
|
8
|
+
Sources:`);for(let B of K.slice(0,$))X.push(`- [${B.title||B.url}](${B.url})`)}}import{spawn as w0}from"node:child_process";import{existsSync as D0}from"node:fs";import{join as G0}from"node:path";import{basename as H0}from"node:path";function R(J=process.env,X=process.execPath){let $=J.GREEDY_SEARCH_NODE||J.NODE_BINARY||J.NODE;if($?.trim())return $.trim();let K=H0(X||"").toLowerCase();if(K==="node"||K==="node.exe")return X;return"node"}function C(J){let X=String(J??"").trim();if(!X)return null;let $=[X],K=X.indexOf("{"),B=X.lastIndexOf("}");if(K>=0&&B>K)$.push(X.slice(K,B+1));for(let Q of $)try{let W=JSON.parse(Q);if(W&&typeof W==="object"&&!Array.isArray(W))return W}catch{}return null}function r(J,X={}){let $=C(J);if(!$)return null;return{...$,_process:{...$._process&&typeof $._process==="object"?$._process:{},status:"partial",...X}}}import{existsSync as _,mkdirSync as M0,readFileSync as n,writeFileSync as b0}from"node:fs";import{homedir as A0}from"node:os";import{join as s}from"node:path";import{tmpdir as N}from"node:os";function O0(J,X=9222){let $=Number.parseInt(String(J??""),10);return Number.isInteger($)&&$>1024&&$<65535?$:X}var a0=O0(process.env.GREEDY_SEARCH_PORT,9222),e=(process.env.GREEDY_SEARCH_PROFILE_DIR||process.env.CDP_PROFILE_DIR||`${N().replaceAll("\\","/")}/greedysearch-chrome-profile`).replaceAll("\\","/"),n0=`${e}/DevToolsActivePort`,s0=`${N().replaceAll("\\","/")}/cdp-pages.json`,e0=process.env.GREEDY_SEARCH_MODE_FILE||`${N().replaceAll("\\","/")}/greedysearch-chrome-mode`,J1=`${N().replaceAll("\\","/")}/greedysearch-visible-recovery.jsonl`,I=s(A0(),".dm"),U=s(I,"greedyconfig"),x=["perplexity","google","chatgpt"],T="gemini";function j0(){try{if(_(U)){let J=n(U,"utf8"),X=JSON.parse(J);if(Array.isArray(X.engines)&&X.engines.length>0&&X.engines.every(($)=>typeof $==="string")){let $=X.engines.filter((B)=>F[B]),K=X.engines.filter((B)=>!F[B]);if(K.length>0)process.stderr.write(`[greedysearch] Warning: ignoring unknown engine(s) in ${U}: ${K.join(", ")}
|
|
9
|
+
[greedysearch] Available engines: ${Object.keys(F).join(", ")}
|
|
10
|
+
`);if($.length>0)return $;process.stderr.write(`[greedysearch] Warning: no valid engines in ${U}, falling back to defaults: ${x.join(", ")}
|
|
11
|
+
`)}}}catch{}return x}function P0(){try{if(!_(I))M0(I,{recursive:!0});if(!_(U))b0(U,JSON.stringify({engines:x,synthesizer:T},null,2)+`
|
|
12
|
+
`,"utf8")}catch{}}P0();var a=["gemini","chatgpt"];function U0(){try{if(_(U)){let J=n(U,"utf8"),X=JSON.parse(J);if(typeof X.synthesizer==="string"){let $=X.synthesizer.toLowerCase();if(a.includes($))return $;process.stderr.write(`[greedysearch] Warning: unknown synthesizer "${X.synthesizer}" in ${U}
|
|
13
|
+
[greedysearch] Available synthesizers: ${a.join(", ")}
|
|
14
14
|
[greedysearch] Falling back to default: ${T}
|
|
15
|
-
`)}}}catch{}return T}var
|
|
16
|
-
`)){let D
|
|
17
|
-
`).flatMap((
|
|
18
|
-
`).map((Z)=>
|
|
15
|
+
`)}}}catch{}return T}var F={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"},S=j0();var X1=U0(),$1=Math.max(1,Number.parseInt(process.env.GREEDY_FETCH_CONCURRENCY||"5",10)||5);process.env.CDP_PROFILE_DIR=e;function E(J){return J.replace(/^"|"$/g,"")}function v(J){return D0(G0(J,"bin","cdp.mjs"))}function J0(){return{content:[{type:"text",text:"cdp.mjs missing — try reinstalling: Rebuild or reinstall DM to refresh the bundled GreedySearch asset."}],details:{}}}function X0(J,X){let $=X instanceof Error?X.message:String(X);return{content:[{type:"text",text:`${J}: ${$}`}],details:{}}}function $0(J,X,$,K,B,Q,W={}){return new Promise((V,q)=>{let{headless:Z=!0}=W,M=[...$];if(Z!==!1&&process.env.GREEDY_SEARCH_VISIBLE!=="1")M.push("--headless");if(Z===!1)M.push("--always-visible");let b={...process.env};if(Z===!1)b.GREEDY_SEARCH_VISIBLE="1",b.GREEDY_SEARCH_ALWAYS_VISIBLE="1";let k=w0(R(),[K,J,"--inline","--stdin",...M],{stdio:["pipe","pipe","pipe"],env:b});k.stdin.write(X),k.stdin.end();let H="",O="",j=()=>{k.kill("SIGTERM"),q(Error("Aborted"))};B?.addEventListener("abort",j,{once:!0}),k.stderr.on("data",(A)=>{O+=A;let Y=/^PROGRESS:(perplexity|google|chatgpt|bing|gemini|semantic-scholar|semanticscholar|s2|logically):(done|error|needs-human)$/;for(let D of A.toString().split(`
|
|
16
|
+
`)){let G=D.match(Y);if(G&&Q)Q(G[1],G[2]);let w=D.match(/^PROGRESS:synthesis:(done|error|skipped)$/);if(w&&Q)Q("synthesis",w[1])}}),k.stdout.on("data",(A)=>H+=A),k.on("close",(A)=>{if(B?.removeEventListener("abort",j),A!==0){let Y=O.trim()||`search.mjs exited with code ${A}`,D=r(H,{code:A,error:Y});if(D){V(D);return}q(Error(Y))}else{let Y=C(H);if(Y)V(Y);else q(Error(`Invalid JSON from search.mjs: ${H.slice(0,200)}`))}})})}function K0(J,X,$,K){let B=new Map;return(Q,W)=>{B.set(Q,W);let V=[];for(let q of J){let Z=B.get(q);if(Z==="done")V.push(`✅ ${q} done`);else if(Z==="error")V.push(`❌ ${q} failed`);else if(Z==="needs-human")V.push(`\uD83D\uDD13 ${q} needs manual verification`);else V.push(`⏳ ${q}`)}if(K&&B.size>=J.length){let q=B.get("synthesis");if(q==="done")V.push("✅ synthesized");else if(q==="error")V.push("❌ synthesis failed");else if(q==="needs-human")V.push("⏭️ synthesis skipped");else V.push("\uD83D\uDD04 synthesizing")}X?.({content:[{type:"text",text:`**${$}...** ${V.join(" · ")}`}],details:{_progress:!0}})}}class P{text;paddingX;paddingY;constructor(J,X=0,$=0){this.text=J;this.paddingX=X;this.paddingY=$}render(J){let X=" ".repeat(this.paddingX),$="",K=Math.max(1,J-this.paddingX*2),B=this.text.split(`
|
|
17
|
+
`).flatMap((Q)=>{if(Q.length<=K)return[`${X}${Q}`];let W=[];for(let V=0;V<Q.length;V+=K)W.push(`${X}${Q.slice(V,V+K)}`);return W});return[...Array.from({length:this.paddingY},()=>""),...B,...Array.from({length:this.paddingY},()=>"")]}invalidate(){}}function B0(J,X){J.registerTool({name:"greedy_search",label:"Greedy Search",description:"WEB/RESEARCH SEARCH ONLY — searches live web via Perplexity, Google AI, ChatGPT, and Gemini, plus opt-in research through Semantic Scholar and Logically. "+"Research mode reuses the configured ~/.dm/greedyconfig engines for child searches and Gemini for planning/final synthesis. Research mode is the centerpiece: it plans follow-up actions, fetches sources, audits citations, and writes a structured research bundle on disk. Use for: library docs, recent framework changes, error messages, best practices, current events. Reports streaming progress as each engine completes.",promptSnippet:"Multi-engine AI web search with streaming progress",parameters:z.Object({query:z.String({description:"The search query"}),engine:z.String({description:'Engine to use: "all" (default), "perplexity", "google", "chatgpt", "gemini", "gem". Research engines: "semantic-scholar" (alias "s2") and "logically". "all" fans out to the configured engines and fetches top sources. Customize via ~/.dm/greedyconfig. Bing Copilot is still available as "bing" for signed-in users.',default:"all"}),synthesize:z.Optional(z.Boolean({description:'Only for engine="all": synthesize the multi-engine results and fetched sources. Default: false.',default:!1})),synthesizer:z.Optional(z.String({description:'Synthesis engine for synthesize=true. Defaults to ~/.dm/greedyconfig synthesizer (currently "gemini" by default). Supported: "gemini", "chatgpt".'})),depth:z.Optional(z.String({description:'Deprecated except "research". Use depth="research" for the iterative research workflow. Research child searches use ~/.dm/greedyconfig engines; Gemini handles research planning/final synthesis. Legacy values: "fast" skips source fetching; "standard"/"deep" alias synthesize=true.'})),breadth:z.Optional(z.Number({description:'Only for depth="research": number of parallel research directions per round, 1-5 (default: 3).',default:3})),iterations:z.Optional(z.Number({description:'Only for depth="research": number of iterative research rounds, 1-3 (default: 2).',default:2})),maxSources:z.Optional(z.Number({description:'Only for depth="research": maximum fetched sources for the final report, 3-12.'})),researchOutDir:z.Optional(z.String({description:'Only for depth="research": optional directory for the structured research bundle. Defaults to .dm/greedysearch-research/<timestamp>_<query>.'})),writeResearchBundle:z.Optional(z.Boolean({description:'Only for depth="research": write the structured research bundle to disk (default true).',default:!0})),fullAnswer:z.Optional(z.Boolean({description:"When true, returns the complete answer instead of a truncated preview (default: false, answers are shortened to ~300 chars to save tokens).",default:!1})),headless:z.Optional(z.Boolean({description:"Set to false to show Chrome window (headless is the default). Set GREEDY_SEARCH_VISIBLE=1 to disable headless globally.",default:!0})),visible:z.Optional(z.Boolean({description:"Set to true to always use visible Chrome for this search. Alias for headless: false.",default:!1})),alwaysVisible:z.Optional(z.Boolean({description:"Set to true to keep GreedySearch in visible Chrome mode for this search. Alias for visible: true.",default:!1}))}),execute:async($,K,B,Q)=>{let{query:W,fullAnswer:V}=K,q=E(K.engine??"all")||"all",Z=E(K.depth??""),M=Z==="research",b=Z==="fast",k=Z==="standard"||Z==="deep",H=q==="all"&&!b&&(K.synthesize===!0||k),O=M?"all":q,A=!(K.visible===!0||K.alwaysVisible===!0||K.headless===!1||process.env.GREEDY_SEARCH_VISIBLE==="1"||process.env.GREEDY_SEARCH_ALWAYS_VISIBLE==="1");if(!v(X))return J0();let Y=[];if(V??O!=="all")Y.push("--full");if(M){if(Y.push("--depth","research"),typeof K.breadth==="number")Y.push("--breadth",String(K.breadth));if(typeof K.iterations==="number")Y.push("--iterations",String(K.iterations));if(typeof K.maxSources==="number")Y.push("--max-sources",String(K.maxSources));if(typeof K.researchOutDir==="string")Y.push("--research-out-dir",K.researchOutDir);if(K.writeResearchBundle===!1)Y.push("--no-research-bundle")}else if(b)Y.push("--fast");else if(Z==="deep")Y.push("--depth","deep");else if(H)Y.push("--synthesize");if(H&&typeof K.synthesizer==="string")Y.push("--synthesizer",K.synthesizer);let G=O==="all"?K0(S,Q,M?"Researching":"Searching",H):void 0;try{let w=await $0(O,W,Y,`${X}/bin/search.mjs`,B,G,{headless:A});return{content:[{type:"text",text:i(O,w)||"No results returned."}],details:{raw:w}}}catch(w){return X0("Search failed",w)}},renderCall($,K){let B=($.query||"").slice(0,60),Q=B.length<($.query||"").length?`${B}...`:B,W=$.engine&&$.engine!=="all"?K.fg("dim",` (${$.engine})`):"";return new P(`${K.fg("toolTitle",K.bold("greedy_search"))} "${K.fg("accent",Q)}"${W}`,0,0)},renderResult($,{expanded:K,isPartial:B},Q){if(B){let Z=$.content.find((b)=>b.type==="text")?.text,M=Z?Z.replace(/\*\*/g,""):"Searching...";return new P(Q.fg("warning",M),0,0)}let W=$.content.find((Z)=>Z.type==="text"),V=$.details?.raw;if(!K){if(V?._needsHumanVerification)return new P(Q.fg("warning"," → Manual verification required"),0,0);let M=V?._synthesis,b=V?._sources;if(M){let j=Array.isArray(b)?b.length:0,A=M.agreement?.level,Y=" → Synthesized";if(j>0)Y+=` · ${j} source${j>1?"s":""}`;if(A)Y+=` · ${A}`;return new P(Q.fg("muted",Y),0,0)}let k=Object.keys(V||{}).filter((j)=>!j.startsWith("_")),H=0;for(let j of k){let Y=V?.[j]?.sources;if(Array.isArray(Y))H+=Y.length}if(H>0)return new P(Q.fg("muted",` → ${H} source${H>1?"s":""}`),0,0);let O=W?.text;if(O)return new P(Q.fg("warning",` → ${O.slice(0,80)}`),0,0);return new P(Q.fg("muted"," → Done"),0,0)}if(!W||W.type!=="text")return new P("",0,0);let q=W.text.split(`
|
|
18
|
+
`).map((Z)=>Q.fg("toolOutput",Z)).join(`
|
|
19
19
|
`);return new P(`
|
|
20
|
-
${q}`,0,0)}})}var
|
|
20
|
+
${q}`,0,0)}})}var g=F0(I0(import.meta.url));function x0(J){J.on("session_start",async(X,$)=>{if(!v(g))$.ui.notify("GreedySearch: cdp.mjs missing from package directory — try reinstall DM or rebuild the bundled GreedySearch asset","warning")}),B0(J,g),J.registerCommand("greedy-visible",{description:"Launch GreedySearch Chrome in visible mode for captcha/login/cookie setup.",handler:async(X,$)=>{await f([],$,"Visible GreedySearch Chrome launched.")}}),J.registerCommand("greedy-status",{description:"Show GreedySearch Chrome status.",handler:async(X,$)=>{await f(["--status"],$)}}),J.registerCommand("greedy-kill",{description:"Stop GreedySearch Chrome.",handler:async(X,$)=>{await f(["--kill"],$,"GreedySearch Chrome stopped.")}}),J.registerCommand("set-greedy-locale",{description:"Set default locale for GreedySearch results (e.g., /set-greedy-locale de, /set-greedy-locale --clear, /set-greedy-locale --show)",handler:async(X,$)=>{let K=X.trim()||"--show";if(K==="--show"){let V=y();if(V.locale)$.ui.notify(`Default locale: ${V.locale}`,"info");else $.ui.notify("No default locale (uses: en)","info");return}if(K==="--clear"){let V=y();delete V.locale,Q0(V),$.ui.notify("Default locale cleared (now uses: en).","info");return}let B=K.toLowerCase(),Q=["en","de","fr","es","it","pt","nl","pl","ru","ja","ko","zh","ar","hi","tr","sv","da","no","fi","cs","hu","ro","el"];if(!Q.includes(B)){$.ui.notify(`Invalid locale "${B}". Valid: ${Q.join(", ")}`,"error");return}let W=y();W.locale=B,Q0(W),$.ui.notify(`Default locale set to: ${B}`,"info")}})}var V0=p(C0(),".config","greedysearch"),h=p(V0,"config.json");async function f(J,X,$){let K=p(g,"bin","visible.mjs"),{code:B,output:Q}=await new Promise((W)=>{let V=L0(R(),[K,...J],{stdio:["ignore","pipe","pipe"],env:{...process.env,GREEDY_SEARCH_VISIBLE:"1"}}),q="";V.stdout.on("data",(Z)=>q+=Z.toString()),V.stderr.on("data",(Z)=>q+=Z.toString()),V.on("close",(Z)=>W({code:Z,output:q}))});if(B===0)X.ui.notify(($||Q.trim()||"Done.").trim(),"info");else X.ui.notify(Q.trim()||`GreedySearch Chrome command failed (${B})`,"error")}function y(){try{if(R0(h))return JSON.parse(N0(h,"utf8"))}catch{}return{}}function Q0(J){_0(V0,{recursive:!0}),v0(h,JSON.stringify(J,null,2),"utf8")}export{x0 as default};
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import{execFileSync as
|
|
2
|
-
[greedysearch] Available engines: ${Object.keys(
|
|
3
|
-
`);if(
|
|
4
|
-
`)}}}catch{}return
|
|
5
|
-
`,"utf8")}catch{}}
|
|
6
|
-
[greedysearch] Available synthesizers: ${
|
|
7
|
-
[greedysearch] Falling back to default: ${
|
|
8
|
-
`)}}}catch{}return
|
|
9
|
-
`)[0],10):null}catch{return null}}function y(q){try{if(F()==="win32")C(`${Z("taskkill")} /F /T /PID ${q}`,{stdio:"ignore"});else{try{process.kill(-q,"SIGKILL")}catch{}try{process.kill(q,"SIGKILL")}catch{}}return!0}catch{return!1}}function n(){try{if(Y(u)){let q=U(u,"utf8"),J=JSON.parse(q);if(J&&typeof J.tempDir==="string"&&typeof J.debugPort==="number")return{browserPid:Number.isInteger(J.browserPid)?J.browserPid:void 0,debugPort:J.debugPort,tempDir:J.tempDir,clientPids:Array.isArray(J.clientPids)?J.clientPids.filter((Q)=>Number.isInteger(Q)&&Q>0):[],sessionMode:J.sessionMode==="visible"?"visible":"headless",lastActivity:Number.isFinite(J.lastActivity)?J.lastActivity:0,launchedAt:Number.isFinite(J.launchedAt)?J.launchedAt:0}}}catch{}try{let q=Y(N)?Number.parseInt(U(N,"utf8").trim(),10)||void 0:void 0,J=Y(O)?U(O,"utf8").trim()==="visible"?"visible":"headless":"headless",Q=Y(v)?Number.parseInt(U(v,"utf8").trim(),10)||0:0;return{browserPid:q,debugPort:V,tempDir:B,clientPids:q?[q]:[],sessionMode:J,lastActivity:Q,launchedAt:0}}catch{return null}}function x(q){try{b(u,JSON.stringify({browserPid:q.browserPid,debugPort:q.debugPort,tempDir:q.tempDir,clientPids:[...new Set(q.clientPids.filter((J)=>J>0))],sessionMode:q.sessionMode,lastActivity:q.lastActivity,launchedAt:q.launchedAt},null,2),"utf8")}catch{}try{if(q.browserPid)b(N,String(q.browserPid),"utf8")}catch{}try{b(O,q.sessionMode,"utf8")}catch{}try{b(v,String(q.lastActivity),"utf8")}catch{}}function A(){try{j(u)}catch{}try{j(N)}catch{}try{j(O)}catch{}try{j(v)}catch{}}function Nq(q){if(!q)return q;let J={...q,clientPids:[...new Set([...q.clientPids,process.pid].filter((Q)=>H(Q)||Q===process.pid))]};return x(J),J}function Oq(q){if(!q)return q;let J={...q,clientPids:q.clientPids.filter((Q)=>Q!==process.pid).filter((Q)=>H(Q))};return x(J),J}function Aq(q){let J=Date.now();try{if(q)x({...q,lastActivity:J});else b(v,String(J),"utf8")}catch{}}var c=Number.parseInt(process.env.GREEDY_SEARCH_IDLE_TIMEOUT_MINUTES||"5",10)||5;function Gq(q){if(c<=0)return!1;if(!q||!q.lastActivity)return!1;return(Date.now()-q.lastActivity)/60000>=c}var p=!1;function Xq(){if(p)return;p=!0;let q=n();if(!q)return;if(q.browserPid){if(!H(q.browserPid)){y(q.browserPid),A();return}if(!g(q.browserPid,q.tempDir,q.debugPort))A();else x({...q,clientPids:q.clientPids.filter(($)=>H($))})}let J=P();if(J&&J!==q.browserPid)if(g(J,B,V))x({browserPid:J,debugPort:V,tempDir:B,clientPids:[J],sessionMode:q.sessionMode,lastActivity:Date.now(),launchedAt:Date.now()});else y(J)}function Tq(){e(E(),{recursive:!0});try{let q=JSON.stringify({pid:process.pid,ts:Date.now()});return b(K,q,{encoding:"utf8",flag:"wx"}),{acquired:!0,release:()=>{try{let J=U(K,"utf8");if(JSON.parse(J).pid===process.pid)j(K)}catch{}}}}catch(q){if(q?.code!=="EEXIST")return{acquired:!1,release:()=>{}}}try{let q=U(K,"utf8"),J=JSON.parse(q),Q=Date.now()-(J.ts||0);if(!H(J.pid)||Q>qq){try{j(K)}catch{}try{let $=JSON.stringify({pid:process.pid,ts:Date.now()});return b(K,$,{encoding:"utf8",flag:"wx"}),{acquired:!0,release:()=>{try{j(K)}catch{}}}}catch{return{acquired:!1,release:()=>{}}}}}catch{}return{acquired:!1,release:()=>{}}}function m(){let q=n();if(!q||!q.browserPid){let X=P();if(X&&g(X,B,V))return{running:!0,pid:X,metadata:q};return{running:!1,pid:null,metadata:null}}if(!H(q.browserPid))return{running:!1,pid:null,metadata:q};if(!g(q.browserPid,q.tempDir,q.debugPort)){let X=P();if(X&&g(X,B,V))return{running:!0,pid:X,metadata:q};return{running:!1,pid:null,metadata:q}}return{running:!0,pid:q.browserPid,metadata:q}}function Dq(){let{running:q,pid:J}=m();if(!q||!J)return A(),!1;let Q=y(J);return A(),Q}async function Rq(){return Xq(),m()}export{x as writeMetadata,g as verifyBrowserProcess,Oq as unregisterClient,Aq as touchActivity,Nq as registerClient,n as readMetadata,Dq as killChrome,Gq as isIdleExpired,Rq as ensureCleanSession,Qq as commandLineMatchesGreedyChrome,A as clearMetadata,Xq as cleanupStaleSessions,m as checkRunning,Tq as acquireLaunchLock,u as METADATA_FILE};
|
|
1
|
+
import{execFileSync as _,execSync as Bq}from"node:child_process";import{existsSync as K,mkdirSync as Vq,readFileSync as U,unlinkSync as j,writeFileSync as b}from"node:fs";import{platform as E,tmpdir as p}from"node:os";import{existsSync as N,mkdirSync as o,readFileSync as S,writeFileSync as s}from"node:fs";import{homedir as i}from"node:os";import{join as F}from"node:path";import{tmpdir as T}from"node:os";function r(q,J=9222){let X=Number.parseInt(String(q??""),10);return Number.isInteger(X)&&X>1024&&X<65535?X:J}var B=r(process.env.GREEDY_SEARCH_PORT,9222),V=(process.env.GREEDY_SEARCH_PROFILE_DIR||process.env.CDP_PROFILE_DIR||`${T().replaceAll("\\","/")}/greedysearch-chrome-profile`).replaceAll("\\","/"),gq=`${V}/DevToolsActivePort`,xq=`${T().replaceAll("\\","/")}/cdp-pages.json`,hq=process.env.GREEDY_SEARCH_MODE_FILE||`${T().replaceAll("\\","/")}/greedysearch-chrome-mode`,wq=`${T().replaceAll("\\","/")}/greedysearch-visible-recovery.jsonl`,D=F(i(),".dm"),Z=F(D,"greedyconfig"),R=["perplexity","google","chatgpt"],C="gemini";function d(){try{if(N(Z)){let q=S(Z,"utf8"),J=JSON.parse(q);if(Array.isArray(J.engines)&&J.engines.length>0&&J.engines.every((X)=>typeof X==="string")){let X=J.engines.filter((W)=>f[W]),$=J.engines.filter((W)=>!f[W]);if($.length>0)process.stderr.write(`[greedysearch] Warning: ignoring unknown engine(s) in ${Z}: ${$.join(", ")}
|
|
2
|
+
[greedysearch] Available engines: ${Object.keys(f).join(", ")}
|
|
3
|
+
`);if(X.length>0)return X;process.stderr.write(`[greedysearch] Warning: no valid engines in ${Z}, falling back to defaults: ${R.join(", ")}
|
|
4
|
+
`)}}}catch{}return R}function t(){try{if(!N(D))o(D,{recursive:!0});if(!N(Z))s(Z,JSON.stringify({engines:R,synthesizer:C},null,2)+`
|
|
5
|
+
`,"utf8")}catch{}}t();var P=["gemini","chatgpt"];function e(){try{if(N(Z)){let q=S(Z,"utf8"),J=JSON.parse(q);if(typeof J.synthesizer==="string"){let X=J.synthesizer.toLowerCase();if(P.includes(X))return X;process.stderr.write(`[greedysearch] Warning: unknown synthesizer "${J.synthesizer}" in ${Z}
|
|
6
|
+
[greedysearch] Available synthesizers: ${P.join(", ")}
|
|
7
|
+
[greedysearch] Falling back to default: ${C}
|
|
8
|
+
`)}}}catch{}return C}var f={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"},Yq=d();var Oq=e(),Nq=Math.max(1,Number.parseInt(process.env.GREEDY_FETCH_CONCURRENCY||"5",10)||5);process.env.CDP_PROFILE_DIR=V;import{execFileSync as qq}from"node:child_process";import{platform as Jq}from"node:os";import{existsSync as L}from"node:fs";import{platform as a}from"node:os";import{join as z}from"node:path";function v(q){let J=a()==="win32",X=process.env.SystemRoot||"C:\\Windows",$={win32:{powershell:z(X,"System32","WindowsPowerShell","v1.0","powershell.exe"),powershell_ise:z(X,"System32","WindowsPowerShell","v1.0","powershell_ise.exe"),netstat:z(X,"System32","netstat.exe"),taskkill:z(X,"System32","taskkill.exe"),tasklist:z(X,"System32","tasklist.exe"),cmd:z(X,"System32","cmd.exe")},unix:{ps:"/usr/bin/ps",lsof:"/usr/bin/lsof",ss:"/usr/sbin/ss",grep:"/usr/bin/grep",kill:"/usr/bin/kill"}},W=J?$.win32:$.unix,Q=q.toLowerCase();if(W[Q]&&L(W[Q]))return W[Q];if(J&&Q==="netstat"){let O=z(X,"Sysnative","netstat.exe");if(L(O))return O}return q}function Xq(q,J){return qq(v(q),J,{encoding:"utf8",stdio:["ignore","pipe","ignore"],timeout:5000})}function $q(q){let J=String(q||"").match(/\b(\d+)\b/);return J?Number.parseInt(J[1],10):null}function Wq(q){return $q(q)}function Qq(q,J){for(let X of String(q||"").split(/\r?\n/)){if(!/\bLISTEN\b/i.test(X))continue;if(!X.trim().split(/\s+/).slice(0,6).some((Q)=>Q.endsWith(`:${J}`)))continue;let W=X.match(/\bpid=(\d+)\b/);if(W)return Number.parseInt(W[1],10)}return null}function Zq(q,J){for(let X of String(q||"").split(/\r?\n/)){let $=X.trim().split(/\s+/);if($.length<5||$[0].toUpperCase()!=="TCP")continue;if(!$.at(-2)?.toUpperCase().startsWith("LISTEN"))continue;if(!$[1].endsWith(`:${J}`))continue;let Q=Number.parseInt($.at(-1),10);if(Number.isInteger(Q)&&Q>0)return Q}return null}function y(q,J,X){try{return q(J,X)}catch{return null}}function I(q,{platformName:J=Jq(),run:X=Xq}={}){if(J==="win32")return Zq(y(X,"netstat",["-ano","-p","TCP"]),q);let $=y(X,"lsof",["-nP",`-iTCP:${q}`,"-sTCP:LISTEN","-t"]),W=Wq($);if(W)return W;if(J!=="linux")return null;return Qq(y(X,"ss",["-ltnp"]),q)}var Y=p().replaceAll("\\","/"),A=`${Y}/greedysearch-chrome-metadata.json`,H=`${Y}/greedysearch-chrome-launch.lock`,zq=15000,g=`${Y}/greedysearch-chrome.pid`,x=`${Y}/greedysearch-chrome-mode`,M=`${Y}/greedysearch-chrome-last-activity`;function k(q){if(!Number.isInteger(q)||q<=0)return!1;try{return process.kill(q,0),!0}catch{return!1}}function Kq(q){if(!k(q))return null;try{if(E()==="win32")return _(v("powershell"),["-NoProfile","-NonInteractive","-Command",`(Get-CimInstance Win32_Process -Filter "ProcessId = ${q}").CommandLine`],{encoding:"utf8",windowsHide:!0,timeout:5000}).trim()||null;return _(v("ps"),["-p",String(q),"-o","command="],{encoding:"utf8",timeout:5000}).trim()||null}catch{return null}}function Hq(q,J,X=B){if(!q)return!1;let $=(O)=>String(O||"").replaceAll("\\","/").toLowerCase(),W=$(q),Q=$(J);return W.includes(Q)&&W.includes(`--remote-debugging-port=${X}`)&&!W.includes("--type=")}function h(q,J,X=B){return Hq(Kq(q),J,X)}function u(q=B){return I(q)}function jq(q){try{if(E()==="win32")Bq(`${v("taskkill")} /F /T /PID ${q}`,{stdio:"ignore"});else{try{process.kill(-q,"SIGKILL")}catch{}try{process.kill(q,"SIGKILL")}catch{}}return!0}catch{return!1}}function m(){try{if(K(A)){let q=U(A,"utf8"),J=JSON.parse(q);if(J&&typeof J.tempDir==="string"&&typeof J.debugPort==="number")return{browserPid:Number.isInteger(J.browserPid)?J.browserPid:void 0,debugPort:J.debugPort,tempDir:J.tempDir,clientPids:Array.isArray(J.clientPids)?J.clientPids.filter((X)=>Number.isInteger(X)&&X>0):[],sessionMode:J.sessionMode==="visible"?"visible":"headless",lastActivity:Number.isFinite(J.lastActivity)?J.lastActivity:0,launchedAt:Number.isFinite(J.launchedAt)?J.launchedAt:0}}}catch{}try{if(!(K(g)||K(x)||K(M)))return null;let J=K(g)?Number.parseInt(U(g,"utf8").trim(),10)||void 0:void 0,X=K(x)?U(x,"utf8").trim()==="visible"?"visible":"headless":"headless",$=K(M)?Number.parseInt(U(M,"utf8").trim(),10)||0:0;return{browserPid:J,debugPort:B,tempDir:V,clientPids:J?[J]:[],sessionMode:X,lastActivity:$,launchedAt:0}}catch{return null}}function w(q){try{b(A,JSON.stringify({browserPid:q.browserPid,debugPort:q.debugPort,tempDir:q.tempDir,clientPids:[...new Set(q.clientPids.filter((J)=>J>0))],sessionMode:q.sessionMode,lastActivity:q.lastActivity,launchedAt:q.launchedAt},null,2),"utf8")}catch{}try{if(q.browserPid)b(g,String(q.browserPid),"utf8")}catch{}try{b(x,q.sessionMode,"utf8")}catch{}try{b(M,String(q.lastActivity),"utf8")}catch{}}function G(){try{j(A)}catch{}try{j(g)}catch{}try{j(x)}catch{}try{j(M)}catch{}}function cq(q){if(!q)return q;let J={...q,clientPids:[...new Set([...q.clientPids,process.pid].filter((X)=>k(X)||X===process.pid))]};return w(J),J}function lq(q){if(!q)return q;let J={...q,clientPids:q.clientPids.filter((X)=>X!==process.pid).filter((X)=>k(X))};return w(J),J}function Eq(q){let J=Date.now();try{if(q)w({...q,lastActivity:J});else b(M,String(J),"utf8")}catch{}}var c=Number.parseInt(process.env.GREEDY_SEARCH_IDLE_TIMEOUT_MINUTES||"5",10)||5;function pq(q){if(c<=0)return!1;if(!q||!q.lastActivity)return!1;return(Date.now()-q.lastActivity)/60000>=c}var l=!1;function bq(){if(l)return;l=!0;let q=m();if(!q)return;if(q.browserPid){if(!k(q.browserPid)){G();return}if(!h(q.browserPid,q.tempDir,q.debugPort))G();else w({...q,clientPids:q.clientPids.filter((W)=>k(W))})}let J=u();if(J&&J!==q.browserPid)if(h(J,V,B))w({browserPid:J,debugPort:B,tempDir:V,clientPids:[J],sessionMode:q.sessionMode,lastActivity:Date.now(),launchedAt:Date.now()});else return}function mq(){Vq(p(),{recursive:!0});try{let q=JSON.stringify({pid:process.pid,ts:Date.now()});return b(H,q,{encoding:"utf8",flag:"wx"}),{acquired:!0,release:()=>{try{let J=U(H,"utf8");if(JSON.parse(J).pid===process.pid)j(H)}catch{}}}}catch(q){if(q?.code!=="EEXIST")return{acquired:!1,release:()=>{}}}try{let q=U(H,"utf8"),J=JSON.parse(q),X=Date.now()-(J.ts||0);if(!k(J.pid)||X>zq){try{j(H)}catch{}try{let W=JSON.stringify({pid:process.pid,ts:Date.now()});return b(H,W,{encoding:"utf8",flag:"wx"}),{acquired:!0,release:()=>{try{j(H)}catch{}}}}catch{return{acquired:!1,release:()=>{}}}}}catch{}return{acquired:!1,release:()=>{}}}function n(){let q=m();if(!q||!q.browserPid){let $=u();if($&&h($,V,B))return{running:!0,pid:$,metadata:q};return{running:!1,pid:null,metadata:null}}if(!k(q.browserPid))return{running:!1,pid:null,metadata:q};if(!h(q.browserPid,q.tempDir,q.debugPort)){let $=u();if($&&h($,V,B))return{running:!0,pid:$,metadata:q};return{running:!1,pid:null,metadata:q}}return{running:!0,pid:q.browserPid,metadata:q}}function nq(){let{running:q,pid:J}=n();if(!q||!J)return G(),!1;let X=jq(J);return G(),X}async function oq(){return bq(),n()}export{w as writeMetadata,h as verifyBrowserProcess,lq as unregisterClient,Eq as touchActivity,cq as registerClient,m as readMetadata,nq as killChrome,pq as isIdleExpired,oq as ensureCleanSession,Hq as commandLineMatchesGreedyChrome,G as clearMetadata,bq as cleanupStaleSessions,n as checkRunning,mq as acquireLaunchLock,A as METADATA_FILE};
|