@duckmind/dm-darwin-x64 0.52.6 → 0.53.4
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 +14 -10
- package/extensions/dm-cua/bin/browser-cua.mjs +6 -6
- package/extensions/dm-cua/index.js +5 -5
- package/extensions/dm-cua/src/browser-cua-lib.mjs +2 -2
- package/extensions/greedysearch-dm/bin/cdp-greedy.mjs +8 -1
- package/extensions/greedysearch-dm/bin/cdp-headless.mjs +1 -1
- package/extensions/greedysearch-dm/bin/cdp-visible.mjs +1 -1
- package/extensions/greedysearch-dm/bin/cdp.mjs +29 -20
- package/extensions/greedysearch-dm/bin/gschrome.mjs +1 -8
- package/extensions/greedysearch-dm/bin/kill-visible.mjs +1 -1
- package/extensions/greedysearch-dm/bin/launch-visible.mjs +1 -2
- package/extensions/greedysearch-dm/bin/launch.mjs +9 -11
- package/extensions/greedysearch-dm/bin/mcp.mjs +375 -0
- package/extensions/greedysearch-dm/bin/search.mjs +309 -157
- package/extensions/greedysearch-dm/bin/visible.mjs +1 -1
- package/extensions/greedysearch-dm/extractors/bing-copilot.mjs +205 -68
- package/extensions/greedysearch-dm/extractors/chatgpt.mjs +229 -140
- package/extensions/greedysearch-dm/extractors/common.mjs +160 -50
- package/extensions/greedysearch-dm/extractors/consensus.mjs +226 -93
- package/extensions/greedysearch-dm/extractors/consent.mjs +44 -17
- package/extensions/greedysearch-dm/extractors/gemini.mjs +277 -138
- package/extensions/greedysearch-dm/extractors/google-ai.mjs +172 -64
- package/extensions/greedysearch-dm/extractors/logically.mjs +183 -69
- package/extensions/greedysearch-dm/extractors/perplexity.mjs +331 -65
- package/extensions/greedysearch-dm/extractors/semantic-scholar.mjs +118 -41
- package/extensions/greedysearch-dm/index.js +23 -20
- package/extensions/greedysearch-dm/package.json +8 -3
- package/extensions/greedysearch-dm/skills/greedy-search/skill.md +8 -8
- package/extensions/greedysearch-dm/src/fetcher.mjs +2 -2
- package/extensions/greedysearch-dm/src/formatters/results.js +8 -6
- package/extensions/greedysearch-dm/src/github.mjs +7 -7
- package/extensions/greedysearch-dm/src/reddit.mjs +1 -1
- package/extensions/greedysearch-dm/src/search/browser-lifecycle.mjs +10 -8
- package/extensions/greedysearch-dm/src/search/challenge-detect.mjs +48 -0
- package/extensions/greedysearch-dm/src/search/chrome.mjs +130 -54
- package/extensions/greedysearch-dm/src/search/constants.mjs +6 -6
- package/extensions/greedysearch-dm/src/search/engines.mjs +9 -9
- package/extensions/greedysearch-dm/src/search/fetch-source.mjs +160 -83
- package/extensions/greedysearch-dm/src/search/minimize.mjs +1 -0
- package/extensions/greedysearch-dm/src/search/paths.mjs +1 -1
- package/extensions/greedysearch-dm/src/search/pdf.mjs +1 -1
- package/extensions/greedysearch-dm/src/search/port-pid.mjs +1 -1
- package/extensions/greedysearch-dm/src/search/progress.mjs +2 -0
- package/extensions/greedysearch-dm/src/search/recovery.mjs +1 -1
- package/extensions/greedysearch-dm/src/search/research.mjs +262 -167
- package/extensions/greedysearch-dm/src/search/scale-aware.mjs +11 -0
- package/extensions/greedysearch-dm/src/search/simple-research.mjs +827 -0
- package/extensions/greedysearch-dm/src/search/synthesis-runner.mjs +9 -9
- package/extensions/greedysearch-dm/src/search/synthesis.mjs +10 -10
- package/extensions/greedysearch-dm/src/tools/greedy-search-handler.js +23 -20
- package/extensions/greedysearch-dm/src/tools/shared.js +10 -9
- package/extensions/greedysearch-dm/src/utils/node-runtime.mjs +1 -1
- package/package.json +1 -1
- package/extensions/greedysearch-dm/src/search/cdp-endpoint.mjs +0 -3
- package/extensions/greedysearch-dm/src/search/launcher-paths.mjs +0 -3
- package/extensions/greedysearch-dm/src/search/partial-output.mjs +0 -1
- package/extensions/greedysearch-dm/src/utils/browser-executable.mjs +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{createRequire as
|
|
2
|
+
import{createRequire as U8}from"node:module";var M8=Object.defineProperty;var D8=($)=>$;function z8($,Z){this[$]=D8.bind(null,Z)}var s$=($,Z)=>{for(var X in Z)M8($,X,{get:Z[X],enumerable:!0,configurable:!0,set:z8.bind(Z,X)})};var V0=($,Z)=>()=>($&&(Z=$($=0)),Z);var F$=U8(import.meta.url);import{basename as F8}from"node:path";function H0($=process.env,Z=process.execPath){let X=$.GREEDY_SEARCH_NODE||$.NODE_BINARY||$.NODE;if(X?.trim())return X.trim();let J=F8(Z||"").toLowerCase();if(J==="node"||J==="node.exe")return Z;return"node"}var x0=()=>{};import{spawn as w8}from"node:child_process";import{dirname as P8,join as _8}from"node:path";import{fileURLToPath as k8}from"node:url";function C8($){if(!Array.isArray($)||$.length===0)throw Error("cdp: args must be a non-empty array");if($[0]==="test")return $.map((Z,X)=>l1(Z,X));if(!T8.has($[0]))throw Error(`cdp: unknown subcommand '${$[0]}'`);return $.map((Z,X)=>l1(Z,X))}function l1($,Z){if(typeof $!=="string")throw Error(`cdp: argv[${Z}] must be a string (got ${typeof $})`);if($.includes("\x00"))throw Error(`cdp: argv[${Z}] contains a null byte`);return $}function S0($,Z=30000){return R8($,null,Z)}function R8($,Z=null,X=30000){let J=C8($);return new Promise((W,K)=>{let V=w8(H0(),[A8,...J],{stdio:[Z==null?"ignore":"pipe","pipe","pipe"]});if(Z!=null)V.stdin.write(Z),V.stdin.end();let j="",Y="";V.stdout.on("data",(H)=>j+=H),V.stderr.on("data",(H)=>Y+=H);let Q=setTimeout(()=>{V.kill(),K(Error(`cdp timeout: ${$[0]}`))},X);V.on("close",(H)=>{if(clearTimeout(Q),H===0)W(j.trim());else K(Error(Y.trim()||`cdp exit ${H}`))})})}async function t$($){await S0(["evalraw",$,"Page.addScriptToEvaluateOnNewDocument",JSON.stringify({source:`
|
|
3
3
|
(function() {
|
|
4
4
|
// ── Runtime.enable / CDP detection masking ──────────────
|
|
5
5
|
try { delete window.__REBROWSER_RUNTIME_ENABLE; } catch(_) {}
|
|
@@ -10,40 +10,62 @@ import{createRequire as e2}from"node:module";var s2=Object.defineProperty;var t2
|
|
|
10
10
|
try { delete window._phantom; } catch(_) {}
|
|
11
11
|
try { delete window.Buffer; } catch(_) {}
|
|
12
12
|
|
|
13
|
-
// Real Chrome without automation
|
|
14
|
-
// A literal false
|
|
15
|
-
//
|
|
16
|
-
|
|
13
|
+
// Real Chrome without automation should not expose navigator.webdriver at all.
|
|
14
|
+
// A literal false or an own-property getter returning undefined is itself a
|
|
15
|
+
// common stealth tell; remove both instance and prototype properties when the
|
|
16
|
+
// descriptor is configurable (as it is with --disable-blink-features).
|
|
17
|
+
try { delete navigator.webdriver; } catch(_) {}
|
|
18
|
+
try { delete Navigator.prototype.webdriver; } catch(_) {}
|
|
17
19
|
Object.defineProperty(navigator, 'vendor', { get: () => 'Google Inc.', configurable: true });
|
|
18
20
|
Object.defineProperty(navigator, 'platform', { get: () => 'Win32', configurable: true });
|
|
19
21
|
Object.defineProperty(navigator, 'maxTouchPoints', { get: () => 0, configurable: true });
|
|
20
22
|
Object.defineProperty(navigator, 'pdfViewerEnabled', { get: () => true, configurable: true });
|
|
23
|
+
Object.defineProperty(navigator, 'productSub', { get: () => '20030107', configurable: true });
|
|
24
|
+
Object.defineProperty(navigator, 'product', { get: () => 'Gecko', configurable: true });
|
|
25
|
+
var __greedyMimeTypes = null;
|
|
26
|
+
function __makeMimeTypes() {
|
|
27
|
+
var pdf = { type: 'application/pdf', suffixes: 'pdf', description: 'Portable Document Format', enabledPlugin: null };
|
|
28
|
+
var textPdf = { type: 'text/pdf', suffixes: 'pdf', description: 'Portable Document Format', enabledPlugin: null };
|
|
29
|
+
try { Object.setPrototypeOf(pdf, MimeType.prototype); } catch(_) {}
|
|
30
|
+
try { Object.setPrototypeOf(textPdf, MimeType.prototype); } catch(_) {}
|
|
31
|
+
var m = [pdf, textPdf];
|
|
32
|
+
try { Object.setPrototypeOf(m, MimeTypeArray.prototype); } catch(_) {}
|
|
33
|
+
m.item = function item(i) { return this[i] || null; };
|
|
34
|
+
m.namedItem = function namedItem(name) { return Array.prototype.find.call(this, function(x) { return x && x.type === name; }) || null; };
|
|
35
|
+
return m;
|
|
36
|
+
}
|
|
21
37
|
Object.defineProperty(navigator, 'plugins', {
|
|
22
38
|
get: () => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
39
|
+
__greedyMimeTypes = __greedyMimeTypes || __makeMimeTypes();
|
|
40
|
+
var plugin0 = { name: 'Chrome PDF Plugin', filename: 'internal-pdf-viewer', description: 'Portable Document Format' };
|
|
41
|
+
var plugin1 = { name: 'Chrome PDF Viewer', filename: 'mhjfbmdgcfjbbpaeojofohoefgiehjai', description: '' };
|
|
42
|
+
var plugin2 = { name: 'Native Client', filename: 'internal-nacl-plugin', description: '' };
|
|
43
|
+
try { Object.setPrototypeOf(plugin0, Plugin.prototype); } catch(_) {}
|
|
44
|
+
try { Object.setPrototypeOf(plugin1, Plugin.prototype); } catch(_) {}
|
|
45
|
+
try { Object.setPrototypeOf(plugin2, Plugin.prototype); } catch(_) {}
|
|
46
|
+
var p = [plugin0, plugin1, plugin2];
|
|
47
|
+
p.item = function item(i) { return this[i] || null; };
|
|
48
|
+
p.namedItem = function namedItem(name) { return Array.prototype.find.call(this, function(x) { return x && x.name === name; }) || null; };
|
|
49
|
+
p.refresh = function refresh() {};
|
|
50
|
+
try { Object.setPrototypeOf(p, PluginArray.prototype); } catch(_) {}
|
|
51
|
+
try {
|
|
52
|
+
__greedyMimeTypes[0].enabledPlugin = p[0];
|
|
53
|
+
__greedyMimeTypes[1].enabledPlugin = p[0];
|
|
54
|
+
} catch(_) {}
|
|
29
55
|
return p;
|
|
30
56
|
},
|
|
57
|
+
configurable: true,
|
|
31
58
|
});
|
|
32
59
|
Object.defineProperty(navigator, 'mimeTypes', {
|
|
33
60
|
get: () => {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
{ type: 'text/pdf', suffixes: 'pdf', description: 'Portable Document Format', enabledPlugin: null },
|
|
37
|
-
];
|
|
38
|
-
m.item = function(i) { return m[i] || null; };
|
|
39
|
-
m.namedItem = function(name) { return m.find(function(x) { return x.type === name; }) || null; };
|
|
40
|
-
return m;
|
|
61
|
+
__greedyMimeTypes = __greedyMimeTypes || __makeMimeTypes();
|
|
62
|
+
return __greedyMimeTypes;
|
|
41
63
|
},
|
|
42
64
|
configurable: true,
|
|
43
65
|
});
|
|
44
66
|
Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'], configurable: true });
|
|
45
67
|
try {
|
|
46
|
-
Object.defineProperty(navigator, 'connection', { get: () => ({ effectiveType: '4g', rtt: 50, downlink: 10, saveData: false }), configurable: true });
|
|
68
|
+
Object.defineProperty(navigator, 'connection', { get: () => ({ effectiveType: '4g', rtt: 50, downlink: 10, downlinkMax: Infinity, saveData: false }), configurable: true });
|
|
47
69
|
} catch(_) {}
|
|
48
70
|
if (!navigator.mediaDevices) {
|
|
49
71
|
Object.defineProperty(navigator, 'mediaDevices', {
|
|
@@ -59,6 +81,18 @@ import{createRequire as e2}from"node:module";var s2=Object.defineProperty;var t2
|
|
|
59
81
|
configurable: true,
|
|
60
82
|
});
|
|
61
83
|
}
|
|
84
|
+
// ── Missing platform APIs (headless often lacks these) ─
|
|
85
|
+
try {
|
|
86
|
+
if (!navigator.share) {
|
|
87
|
+
navigator.share = function() { return Promise.reject(new Error('NotAllowedError')); };
|
|
88
|
+
}
|
|
89
|
+
} catch(_) {}
|
|
90
|
+
try {
|
|
91
|
+
if (!navigator.contentIndex) {
|
|
92
|
+
Object.defineProperty(navigator, 'contentIndex', { get: () => ({ add: function() {}, delete: function() {}, getAll: function() { return Promise.resolve([]); } }), configurable: true });
|
|
93
|
+
}
|
|
94
|
+
} catch(_) {}
|
|
95
|
+
|
|
62
96
|
if (!window.chrome) {
|
|
63
97
|
window.chrome = {
|
|
64
98
|
app: { isInstalled: false, InstallState: {}, RunningState: {} },
|
|
@@ -66,8 +100,8 @@ import{createRequire as e2}from"node:module";var s2=Object.defineProperty;var t2
|
|
|
66
100
|
OnInstalledReason: {}, OnRestartRequiredReason: {}, PlatformArch: {}, PlatformNaclArch: {}, PlatformOs: {}, RequestUpdateCheckStatus: {},
|
|
67
101
|
connect: () => ({}), sendMessage: () => {}, onMessage: { addListener: () => {} }
|
|
68
102
|
},
|
|
69
|
-
loadTimes: ()
|
|
70
|
-
csi: ()
|
|
103
|
+
loadTimes: function() { return { requestTime: 0, startLoadTime: Date.now() - 5000, commitLoadTime: Date.now() - 3000, finishDocumentLoadTime: Date.now() - 2000, finishLoadTime: Date.now() - 1000, firstPaintTime: Date.now() - 800, navigationType: 'Other', wasFetchedViaSpdy: true, wasNpnNegotiated: true, npnNegotiatedProtocol: 'h2', wasAlternateProtocolAvailable: false, connectionInfo: 'http/2' }; },
|
|
104
|
+
csi: function() { var t = Date.now(); return { onloadT: t - 2000, startE: t - 5000, pageT: 'back', tran: 2 }; },
|
|
71
105
|
};
|
|
72
106
|
}
|
|
73
107
|
var __greedyNativeFns = [];
|
|
@@ -88,6 +122,19 @@ import{createRequire as e2}from"node:module";var s2=Object.defineProperty;var t2
|
|
|
88
122
|
return getParam.call(this, p);
|
|
89
123
|
});
|
|
90
124
|
} catch(_) {}
|
|
125
|
+
// ── WebGL readPixels noise ──────────────────────────
|
|
126
|
+
// CreepJS and other fingerprinters draw content with WebGL and read back the
|
|
127
|
+
// rendered pixels. Adding subtle noise breaks rendering-based fingerprinting.
|
|
128
|
+
try {
|
|
129
|
+
var origReadPixels = WebGLRenderingContext.prototype.readPixels;
|
|
130
|
+
WebGLRenderingContext.prototype.readPixels = __markNative(function readPixels(x, y, width, height, format, type, pixels) {
|
|
131
|
+
var result = origReadPixels.call(this, x, y, width, height, format, type, pixels);
|
|
132
|
+
if (pixels && pixels.length > 0) {
|
|
133
|
+
pixels[0] ^= 1;
|
|
134
|
+
}
|
|
135
|
+
return result;
|
|
136
|
+
});
|
|
137
|
+
} catch(_) {}
|
|
91
138
|
Object.defineProperty(navigator, 'hardwareConcurrency', { get: () => 8, configurable: true });
|
|
92
139
|
Object.defineProperty(navigator, 'deviceMemory', { get: () => 8, configurable: true });
|
|
93
140
|
|
|
@@ -95,7 +142,7 @@ import{createRequire as e2}from"node:module";var s2=Object.defineProperty;var t2
|
|
|
95
142
|
// Headless rendering engines produce slightly different canvas output
|
|
96
143
|
// than headed Chrome. Subtle noise breaks hash-based fingerprinting.
|
|
97
144
|
try {
|
|
98
|
-
var __canvasNoise = ((Date.now()
|
|
145
|
+
var __canvasNoise = ((Date.now() & 0xFF) | 1);
|
|
99
146
|
var origFill = CanvasRenderingContext2D.prototype.fillText;
|
|
100
147
|
CanvasRenderingContext2D.prototype.fillText = __markNative(function fillText() {
|
|
101
148
|
this.globalAlpha = 0.9995;
|
|
@@ -114,15 +161,39 @@ import{createRequire as e2}from"node:module";var s2=Object.defineProperty;var t2
|
|
|
114
161
|
HTMLCanvasElement.prototype.toDataURL = __markNative(function toDataURL() {
|
|
115
162
|
var ctx = this.getContext('2d');
|
|
116
163
|
if (ctx) {
|
|
117
|
-
//
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
164
|
+
// Spread noise across canvas to break hash-based fingerprinting.
|
|
165
|
+
// Uses a deterministic pattern so it's consistent per page load
|
|
166
|
+
// but varies between sessions.
|
|
167
|
+
var w = this.width, h = this.height;
|
|
168
|
+
if (w > 0 && h > 0) {
|
|
169
|
+
var imgData = ctx.getImageData(0, 0, Math.min(w, 4), Math.min(h, 4));
|
|
170
|
+
if (imgData && imgData.data) {
|
|
171
|
+
for (var __i = 0; __i < imgData.data.length; __i += 4) {
|
|
172
|
+
imgData.data[__i] ^= (__canvasNoise + __i) & 0xFF;
|
|
173
|
+
}
|
|
174
|
+
ctx.putImageData(imgData, 0, 0);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
121
177
|
}
|
|
122
178
|
return origToDataURL.apply(this, arguments);
|
|
123
179
|
});
|
|
124
180
|
} catch(_) {}
|
|
125
181
|
|
|
182
|
+
// ── AudioContext fingerprint noise ────────────────────
|
|
183
|
+
// Headless Chrome's AudioContext produces slightly different output.
|
|
184
|
+
// Subtle noise breaks audio-based fingerprinting.
|
|
185
|
+
try {
|
|
186
|
+
var __audioSeed = ((Date.now() & 0x1F) | 1);
|
|
187
|
+
var origGetChannelData = AudioBuffer.prototype.getChannelData;
|
|
188
|
+
AudioBuffer.prototype.getChannelData = __markNative(function getChannelData(channel) {
|
|
189
|
+
var data = origGetChannelData.call(this, channel);
|
|
190
|
+
for (var __i = 0; __i < data.length; __i += 64) {
|
|
191
|
+
data[__i] *= 0.99999;
|
|
192
|
+
}
|
|
193
|
+
return data;
|
|
194
|
+
});
|
|
195
|
+
} catch(_) {}
|
|
196
|
+
|
|
126
197
|
// ── window outer dimensions ──────────────────────────
|
|
127
198
|
// outerWidth/Height = 0 in headless — a well-known bot signal.
|
|
128
199
|
// Mirror innerWidth/Height (set by --window-size flag) so the ratio is sane.
|
|
@@ -132,9 +203,15 @@ import{createRequire as e2}from"node:module";var s2=Object.defineProperty;var t2
|
|
|
132
203
|
} catch(_) {}
|
|
133
204
|
|
|
134
205
|
// ── screen properties ─────────────────────────────────
|
|
206
|
+
// Headless Chrome often reports an 800x600 screen even when the viewport is
|
|
207
|
+
// 1920x1080. Keep screen metrics internally consistent with our launch flags.
|
|
135
208
|
try {
|
|
136
|
-
|
|
137
|
-
|
|
209
|
+
Object.defineProperty(screen, 'width', { get: () => 1920, configurable: true });
|
|
210
|
+
Object.defineProperty(screen, 'height', { get: () => 1080, configurable: true });
|
|
211
|
+
Object.defineProperty(screen, 'availWidth', { get: () => 1920, configurable: true });
|
|
212
|
+
Object.defineProperty(screen, 'availHeight', { get: () => 1040, configurable: true });
|
|
213
|
+
Object.defineProperty(screen, 'colorDepth', { get: () => 24, configurable: true });
|
|
214
|
+
Object.defineProperty(screen, 'pixelDepth', { get: () => 24, configurable: true });
|
|
138
215
|
} catch(_) {}
|
|
139
216
|
|
|
140
217
|
// ── navigator.userAgentData (UA Client Hints) ─────────
|
|
@@ -207,39 +284,38 @@ import{createRequire as e2}from"node:module";var s2=Object.defineProperty;var t2
|
|
|
207
284
|
};
|
|
208
285
|
} catch(_) {}
|
|
209
286
|
})();
|
|
210
|
-
`})])}var
|
|
211
|
-
[greedysearch] Available engines: ${Object.keys(
|
|
212
|
-
`);if(X.length>0)return X;process.stderr.write(`[greedysearch] Warning: no valid engines in ${
|
|
213
|
-
`)}}}catch{}return
|
|
214
|
-
`,"utf8")}catch{}}function
|
|
215
|
-
[greedysearch] Available synthesizers: ${
|
|
216
|
-
[greedysearch] Falling back to default: ${
|
|
217
|
-
`)}}}catch{}return
|
|
218
|
-
${Z.
|
|
219
|
-
`}function
|
|
220
|
-
${W.
|
|
221
|
-
`)
|
|
222
|
-
`);return Z}async function
|
|
223
|
-
`)[0];if(!Z)throw Error("No Chrome tabs found");return Z.slice(0,8)}async function
|
|
224
|
-
${j}`,"utf8");try{
|
|
225
|
-
`)
|
|
226
|
-
`),await
|
|
227
|
-
`)
|
|
228
|
-
`);let j=[d1({moduleDir:e8,entrypoint:process.argv[1]})];if(process.env.GREEDY_SEARCH_VISIBLE!=="1")j.push("--headless");await new Promise((Q,B)=>{a8($0(),j,{stdio:["ignore",process.stderr,process.stderr]}).on("close",(G)=>G===0?Q():B(Error("launch.mjs failed")))})}finally{V.release()}}var e8,Z2,t0,r0,$6,Z6,T0,q;var $1=l(()=>{R1();E0();B$();Y0();m1();l1();o$();r1();e8=import.meta.dirname||new URL(".",import.meta.url).pathname.replace(/^\/([A-Z]:)/,"$1"),Z2=r8().replaceAll("\\","/"),t0=`${Z2}/greedysearch-chrome.pid`,r0=`${Z2}/greedysearch-chrome-last-activity`,$6=Number.parseInt(process.env.GREEDY_SEARCH_IDLE_TIMEOUT_MINUTES||"5",10)||5,Z6=Number.parseInt(process.env.GREEDY_SEARCH_VISIBLE_IDLE_TIMEOUT_MINUTES||"60",10)||60;T0=K2;q=h$});var O2={};u0(O2,{shouldUseBrowser:()=>_6,rewriteGitHubUrl:()=>M2,isPrivateUrl:()=>k$,fetchSourceHttp:()=>X1,extractContent:()=>F$,detectBotBlock:()=>P$,defaultFetchHeaders:()=>Z1,checkContentQuality:()=>L$});import{Readability as H6}from"@mozilla/readability";import{JSDOM as M6}from"jsdom";import O6 from"turndown";function Z1($={}){return{...H2,...$}}function k$($){try{let Z=new URL($),X=Z.hostname.toLowerCase();for(let J of G6)if(J.test(X))return{blocked:!0,reason:`Private/internal address: ${X}`};if(Z.protocol==="file:")return{blocked:!0,reason:"File protocol not allowed"};return{blocked:!1}}catch(Z){return{blocked:!0,reason:`Invalid URL: ${Z.message}`}}}function M2($){try{let Z=new URL($);if(!(Z.hostname==="github.com"||Z.hostname.endsWith(".github.com")))return $;let X=Z.pathname.split("/").filter(Boolean);if(X.length<5)return $;let[J,W,K,V,...Y]=X;if(K!=="blob")return $;let j=Y.join("/");return`https://raw.githubusercontent.com/${J}/${W}/${V}/${j}`}catch{return $}}async function X1($,Z={}){let X=k$($);if(X.blocked)return{ok:!1,url:$,finalUrl:$,status:403,error:`Blocked: ${X.reason}`,needsBrowser:!1};let J=$;if($=M2($),$!==J)console.error(`[fetcher] Rewrote GitHub URL: ${J.slice(0,60)}... → raw.githubusercontent.com`);let{timeoutMs:W=15000,userAgent:K,signal:V}=Z,Y=new AbortController,j=setTimeout(()=>Y.abort(),W);if(V)V.addEventListener("abort",()=>Y.abort(),{once:!0});try{let Q=await fetch($,{method:"GET",headers:{...H2,"user-agent":K||B2},redirect:"follow",signal:Y.signal});clearTimeout(j);let B=Q.headers.get("content-type")||"",H=Q.url,G=Q.headers.get("last-modified")||"",O=!1;try{O=new URL(H).hostname.toLowerCase()==="raw.githubusercontent.com"}catch{}if(B.includes("text/plain")&&O){let E=await Q.text();return{ok:!0,url:J,finalUrl:H,status:Q.status,title:H.split("/").pop()||"GitHub File",byline:"",siteName:"GitHub",lang:"",publishedTime:G,lastModified:G,markdown:E,contentLength:E.length,excerpt:E.slice(0,300).replaceAll(/\n/g," "),needsBrowser:!1}}if(!B.includes("text/html")&&!B.includes("application/xhtml"))return{ok:!1,url:$,finalUrl:H,status:Q.status,error:`Unsupported content type: ${B}`,needsBrowser:!1};let z=await Q.text(),D=P$(Q.status,z,H,$);if(D.blocked)return{ok:!1,url:$,finalUrl:H,status:Q.status,error:`Blocked: ${D.reason}`,needsBrowser:!0};let M=F$(z,H),k=L$(M);if(!k.ok)return{ok:!1,url:$,finalUrl:H,status:Q.status,error:`Low quality content: ${k.reason}`,needsBrowser:!0};return{ok:!0,url:$,finalUrl:H,status:Q.status,title:M.title,byline:M.byline,siteName:M.siteName,lang:M.lang,publishedTime:M.publishedTime||G,lastModified:G,markdown:M.markdown,excerpt:M.excerpt,contentLength:M.markdown.length,needsBrowser:!1}}catch(Q){clearTimeout(j);let B=A6(Q);return{ok:!1,url:$,finalUrl:$,status:0,error:Q.message,needsBrowser:B}}}function P$($,Z,X,J){let W=Z.match(/<title[^>]*>([^<]*)<\/title>/i)?.[1]?.toLowerCase()||"",K=Z.slice(0,30000).toLowerCase(),V=`${W} ${K}`;if($===403||$===429||$===503)return{blocked:!0,reason:`HTTP ${$}`};let Y=[{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 Q of Y)if(Q.pattern.test(V))return{blocked:!0,reason:Q.reason};let j=U6(J,X,Z);if(j)return{blocked:!0,reason:j};return{blocked:!1}}function U6($,Z,X){try{let J=new URL($),W=new URL(Z);if(J.hostname.toLowerCase()===W.hostname.toLowerCase())return;let K=W.hostname.toLowerCase();if(N6.some((Y)=>K===Y||K.endsWith(`.${Y}`)))return`redirected to login (${W.hostname})`;if(z6.some((Y)=>K.startsWith(Y)))return`redirected to login (${W.hostname})`;let V=X.slice(0,20000).toLowerCase();if(D6.some((Y)=>V.includes(Y)))return`redirected to login page (${W.hostname})`}catch{}return}function A6($){let Z=$.message.toLowerCase();return Z.includes("fetch failed")||Z.includes("unable to verify")||Z.includes("certificate")||Z.includes("timeout")}function j2($){let Z=['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 X of Z){let J=$.querySelector(X),W=J?.getAttribute("content")||J?.getAttribute("datetime")||"";if(W)return W}return""}function F$($,Z){let J=new M6($,{url:Z}).window.document,K=new H6(J).parse();if(K&&K.content){let j=Q2.turndown(K.content).replaceAll(/\n{3,}/g,`
|
|
287
|
+
`})])}var L8,A8,T8;var r$=V0(()=>{x0();L8=P8(k8(import.meta.url)),A8=_8(L8,"..","bin","cdp.mjs"),T8=new Set(["list","snap","eval","shot","html","nav","net","click","clickxy","type","loadall","evalraw","browse","stop","--tab"])});import{existsSync as u1}from"node:fs";import{platform as I8}from"node:os";import{join as g0}from"node:path";function X0($){let Z=I8()==="win32",X=process.env.SystemRoot||"C:\\Windows",J={win32:{powershell:g0(X,"System32","WindowsPowerShell","v1.0","powershell.exe"),powershell_ise:g0(X,"System32","WindowsPowerShell","v1.0","powershell_ise.exe"),netstat:g0(X,"System32","netstat.exe"),taskkill:g0(X,"System32","taskkill.exe"),tasklist:g0(X,"System32","tasklist.exe"),cmd:g0(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=Z?J.win32:J.unix,K=$.toLowerCase();if(W[K]&&u1(W[K]))return W[K];if(Z&&K==="netstat"){let V=g0(X,"Sysnative","netstat.exe");if(u1(V))return V}return $}var w$=()=>{};import{execFileSync as v8}from"node:child_process";import{platform as q8}from"node:os";function E8($,Z){return v8(X0($),Z,{encoding:"utf8",stdio:["ignore","pipe","ignore"],timeout:5000})}function f8($){let Z=String($||"").match(/\b(\d+)\b/);return Z?Number.parseInt(Z[1],10):null}function b8($){return f8($)}function x8($,Z){for(let X of String($||"").split(/\r?\n/)){if(!/\bLISTEN\b/i.test(X))continue;if(!X.trim().split(/\s+/).slice(0,6).some((K)=>K.endsWith(`:${Z}`)))continue;let W=X.match(/\bpid=(\d+)\b/);if(W)return Number.parseInt(W[1],10)}return null}function S8($,Z){for(let X of String($||"").split(/\r?\n/)){let J=X.trim().split(/\s+/);if(J.length<5||J[0].toUpperCase()!=="TCP")continue;if(!J.at(-2)?.toUpperCase().startsWith("LISTEN"))continue;if(!J[1].endsWith(`:${Z}`))continue;let W=Number.parseInt(J.at(-1),10);if(Number.isInteger(W)&&W>0)return W}return null}function e$($,Z,X){try{return $(Z,X)}catch{return null}}function c1($,{platformName:Z=q8(),run:X=E8}={}){if(Z==="win32")return S8(e$(X,"netstat",["-ano","-p","TCP"]),$);let J=e$(X,"lsof",["-nP",`-iTCP:${$}`,"-sTCP:LISTEN","-t"]),W=b8(J);if(W)return W;if(Z!=="linux")return null;return x8(e$(X,"ss",["-ltnp"]),$)}var n1=V0(()=>{w$()});import{existsSync as P$,mkdirSync as g8,readFileSync as i1,writeFileSync as y8}from"node:fs";import{homedir as h8}from"node:os";import{join as a1}from"node:path";import{tmpdir as p8}from"node:os";function m8($,Z=9222){let X=Number.parseInt(String($??""),10);return Number.isInteger(X)&&X>1024&&X<65535?X:Z}function u8(){try{if(P$(k0)){let $=i1(k0,"utf8"),Z=JSON.parse($);if(Array.isArray(Z.engines)&&Z.engines.length>0&&Z.engines.every((X)=>typeof X==="string")){let X=Z.engines.filter((W)=>N0[W]),J=Z.engines.filter((W)=>!N0[W]);if(J.length>0)process.stderr.write(`[greedysearch] Warning: ignoring unknown engine(s) in ${k0}: ${J.join(", ")}
|
|
288
|
+
[greedysearch] Available engines: ${Object.keys(N0).join(", ")}
|
|
289
|
+
`);if(X.length>0)return X;process.stderr.write(`[greedysearch] Warning: no valid engines in ${k0}, falling back to defaults: ${Z1.join(", ")}
|
|
290
|
+
`)}}}catch{}return Z1}function c8(){try{if(!P$($1))g8($1,{recursive:!0});if(!P$(k0))y8(k0,JSON.stringify({engines:Z1,synthesizer:X1},null,2)+`
|
|
291
|
+
`,"utf8")}catch{}}function n8(){try{if(P$(k0)){let $=i1(k0,"utf8"),Z=JSON.parse($);if(typeof Z.synthesizer==="string"){let X=Z.synthesizer.toLowerCase();if(J$.includes(X))return X;process.stderr.write(`[greedysearch] Warning: unknown synthesizer "${Z.synthesizer}" in ${k0}
|
|
292
|
+
[greedysearch] Available synthesizers: ${J$.join(", ")}
|
|
293
|
+
[greedysearch] Falling back to default: ${X1}
|
|
294
|
+
`)}}}catch{}return X1}var d8,n,u,W$,_$,l8,R0,o1,s1,k$,o9,t1,$1,k0,Z1,X1="gemini",J$,N0,r,K$,r1,J1;var D0=V0(()=>{d8=p8().replaceAll("\\","/"),n=m8(process.env.GREEDY_SEARCH_PORT),u=(process.env.GREEDY_SEARCH_PROFILE_DIR||process.env.CDP_PROFILE_DIR||`${d8}/greedysearch-chrome-profile`).replaceAll("\\","/"),W$=`${u}/DevToolsActivePort`,_$=process.env.GREEDY_SEARCH_PID_FILE||`${u}/browser.pid`,l8=process.env.CDP_PAGES_CACHE||`${u}/cdp-pages.json`,R0=process.env.GREEDY_SEARCH_MODE_FILE||`${u}/browser-mode`,o1=process.env.GREEDY_SEARCH_METADATA_FILE||`${u}/browser-metadata.json`,s1=process.env.GREEDY_SEARCH_LAUNCH_LOCK_FILE||`${u}/browser-launch.lock`,k$=process.env.GREEDY_SEARCH_ACTIVITY_FILE||`${u}/browser-last-activity`,o9=(process.env.CDP_SOCKET_DIR||`${u}/cdp-sockets`).replaceAll("\\","/"),t1=`${u}/visible-recovery.jsonl`,$1=a1(h8(),".dm"),k0=a1($1,"greedyconfig"),Z1=["perplexity","google","chatgpt","gemini"];c8();J$=["gemini","chatgpt"];N0={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"},r=u8(),K$=r,r1=n8(),J1=Math.max(1,Number.parseInt(process.env.GREEDY_FETCH_CONCURRENCY||"5",10)||5);process.env.CDP_PROFILE_DIR=u});import{execFileSync as e1,execSync as $2}from"node:child_process";import{existsSync as L$,mkdirSync as i8,readFileSync as a0,unlinkSync as h0,writeFileSync as p0}from"node:fs";import{platform as W2}from"node:os";function j$($){if(!Number.isInteger($)||$<=0)return!1;try{return process.kill($,0),!0}catch{return!1}}function o8($){if(!j$($))return null;try{if(W2()==="win32")return e1(X0("powershell"),["-NoProfile","-NonInteractive","-Command",`(Get-CimInstance Win32_Process -Filter "ProcessId = ${$}").CommandLine`],{encoding:"utf8",windowsHide:!0,timeout:5000}).trim()||null;return e1(X0("ps"),["-p",String($),"-o","command="],{encoding:"utf8",timeout:5000}).trim()||null}catch{return null}}function s8($,Z,X=n){if(!$)return!1;let J=(V)=>String(V||"").replaceAll("\\","/").toLowerCase(),W=J($),K=J(Z);return W.includes(K)&&W.includes(`--remote-debugging-port=${X}`)&&!W.includes("--type=")}function Z2($,Z,X=n){return s8(o8($),Z,X)}function t8($=n){try{if(W2()==="win32"){let X=$2(`${X0("netstat")} -ano -p TCP 2>nul`,{encoding:"utf8"}),J=new RegExp(String.raw`TCP\s+\S+:${$}\s+\S+:0\s+LISTENING\s+(\d+)`,"i"),W=X.match(J);return W?Number.parseInt(W[1],10):null}let Z=$2(`${X0("lsof")} -i :${$} -t 2>/dev/null || ${X0("ss")} -tlnp 2>/dev/null | ${X0("grep")} :${$} | ${X0("grep")} -oP 'pid=\\K\\d+'`,{encoding:"utf8"}).trim();return Z?Number.parseInt(Z.split(`
|
|
295
|
+
`)[0],10):null}catch{return null}}function Y$(){try{if(L$(A$)){let $=a0(A$,"utf8"),Z=JSON.parse($);if(Z&&typeof Z.tempDir==="string"&&typeof Z.debugPort==="number")return{browserPid:Number.isInteger(Z.browserPid)?Z.browserPid:void 0,debugPort:Z.debugPort,tempDir:Z.tempDir,clientPids:Array.isArray(Z.clientPids)?Z.clientPids.filter((X)=>Number.isInteger(X)&&X>0):[],sessionMode:Z.sessionMode==="visible"?"visible":"headless",lastActivity:Number.isFinite(Z.lastActivity)?Z.lastActivity:0,launchedAt:Number.isFinite(Z.launchedAt)?Z.launchedAt:0}}}catch{}try{let $=L$(T$)?Number.parseInt(a0(T$,"utf8").trim(),10)||void 0:void 0,Z=L$(C$)?a0(C$,"utf8").trim()==="visible"?"visible":"headless":"headless",X=L$(V$)?Number.parseInt(a0(V$,"utf8").trim(),10)||0:0;return{browserPid:$,debugPort:n,tempDir:u,clientPids:$?[$]:[],sessionMode:Z,lastActivity:X,launchedAt:0}}catch{return null}}function R$($){try{p0(A$,JSON.stringify({browserPid:$.browserPid,debugPort:$.debugPort,tempDir:$.tempDir,clientPids:[...new Set($.clientPids.filter((Z)=>Z>0))],sessionMode:$.sessionMode,lastActivity:$.lastActivity,launchedAt:$.launchedAt},null,2),"utf8")}catch{}try{if($.browserPid)p0(T$,String($.browserPid),"utf8")}catch{}try{p0(C$,$.sessionMode,"utf8")}catch{}try{p0(V$,String($.lastActivity),"utf8")}catch{}}function X2(){try{h0(A$)}catch{}try{h0(T$)}catch{}try{h0(C$)}catch{}try{h0(V$)}catch{}}function W1($){if(!$)return $;let Z={...$,clientPids:[...new Set([...$.clientPids,process.pid].filter((X)=>j$(X)||X===process.pid))]};return R$(Z),Z}function I$($){let Z=Date.now();try{if($)R$({...$,lastActivity:Z});else p0(V$,String(Z),"utf8")}catch{}}function K2(){if(process.env.GREEDY_SEARCH_RESEARCH_CHILD)return;if(J2)return;J2=!0;let $=Y$();if(!$)return;if($.browserPid){if(!j$($.browserPid)){X2();return}if(!Z2($.browserPid,$.tempDir,$.debugPort))X2();else R$({...$,clientPids:$.clientPids.filter((W)=>j$(W))})}let Z=t8();if(Z&&Z!==$.browserPid)if(Z2(Z,u,n))R$({browserPid:Z,debugPort:n,tempDir:u,clientPids:[Z],sessionMode:$.sessionMode,lastActivity:Date.now(),launchedAt:Date.now()});else process.stderr.write(`[greedysearch] Refusing to kill unverified listener ${Z} on port ${n}.
|
|
296
|
+
`)}function V2(){i8(u,{recursive:!0});try{let $=JSON.stringify({pid:process.pid,ts:Date.now()});return p0(y0,$,{encoding:"utf8",flag:"wx"}),{acquired:!0,release:()=>{try{let Z=a0(y0,"utf8");if(JSON.parse(Z).pid===process.pid)h0(y0)}catch{}}}}catch($){if($?.code!=="EEXIST")return{acquired:!1,release:()=>{}}}try{let $=a0(y0,"utf8"),Z=JSON.parse($),X=Date.now()-(Z.ts||0);if(!j$(Z.pid)||X>a8){try{h0(y0)}catch{}try{let W=JSON.stringify({pid:process.pid,ts:Date.now()});return p0(y0,W,{encoding:"utf8",flag:"wx"}),{acquired:!0,release:()=>{try{h0(y0)}catch{}}}}catch{return{acquired:!1,release:()=>{}}}}}catch{}return{acquired:!1,release:()=>{}}}var A$,y0,a8=15000,T$,C$,V$,X4,J2=!1;var j2=V0(()=>{D0();w$();A$=o1,y0=s1,T$=_$,C$=R0,V$=k$;X4=Number.parseInt(process.env.GREEDY_SEARCH_IDLE_TIMEOUT_MINUTES||"5",10)||5});import{spawn as r8,execFileSync as K1,execSync as K4}from"node:child_process";import{existsSync as H2,readFileSync as V1,renameSync as e8,unlinkSync as L0,writeFileSync as q$}from"node:fs";import j1 from"node:http";import{platform as B2}from"node:os";import{join as $6}from"node:path";function W6($,Z=n){let X=String($||"").toLowerCase();if(!X.includes(`--remote-debugging-port=${Z}`)||X.includes("--type="))return null;return X.includes("--headless")}function G2(){try{let $=b$(),Z=$?N2($):null,X=W6(Z);if(X!==null){try{q$(R0,X?"headless":"visible","utf8")}catch{}return X}}catch{}try{if(!H2(R0))return!0;return V1(R0,"utf8").trim()==="headless"}catch{return!0}}function f$(){try{q$(Q$,String(Date.now()),"utf8")}catch{}try{let $=Y$();if($)I$($)}catch{}}function N2($){try{if(B2()==="win32")return K1(X0("powershell"),["-NoProfile","-NonInteractive","-Command",`(Get-CimInstance Win32_Process -Filter "ProcessId = ${$}").CommandLine`],{encoding:"utf8",windowsHide:!0,timeout:5000}).trim()||null;return K1(X0("ps"),["-p",String($),"-o","command="],{encoding:"utf8",timeout:5000}).trim()||null}catch{return null}}function K6($){let Z=String($||"").replaceAll("\\","/"),X=u.replaceAll("\\","/");return Z.includes(`--remote-debugging-port=${n}`)&&Z.includes(`--user-data-dir=${X}`)&&!Z.includes("--type=")}function b$(){return c1(n)}function E$(){let $=b$();return $&&K6(N2($))?$:null}async function V6($=1500){let Z=E$();if(!Z)return process.stderr.write(`[greedysearch] Refusing to close an unverified listener.
|
|
297
|
+
`),!1;try{let J=await new Promise((K,V)=>{let j=j1.get(`http://localhost:${n}/json/version`,(Y)=>{let Q="";Y.on("data",(H)=>Q+=H),Y.on("end",()=>{try{K(JSON.parse(Q))}catch{V(Error("bad JSON"))}})});j.on("error",V),j.setTimeout(1000,()=>{j.destroy(),V(Error("timeout"))})}),W=new globalThis.WebSocket(J.webSocketDebuggerUrl);await new Promise((K)=>{W.onopen=()=>{if(E$()!==Z){W.close(),K();return}W.send(JSON.stringify({id:1,method:"Browser.close"})),setTimeout(()=>{W.close(),K()},200)},W.onerror=()=>K(),setTimeout(K,1000)})}catch{}let X=Date.now()+$;while(Date.now()<X){let J=b$();if(!J)return!0;if(J!==Z)return!1;await new Promise((W)=>setTimeout(W,150))}return j6(Z)}function j6($=null){try{let Z=E$();if(!Z||$&&Z!==$)return!1;if(B2()==="win32")K1(X0("taskkill"),["/F","/PID",String(Z)],{stdio:"ignore",windowsHide:!0});else process.kill(Z,"SIGKILL");return!0}catch{return!1}}async function O2(){if(!E$()){if(b$())process.stderr.write(`[greedysearch] Refusing to kill an unverified listener.
|
|
298
|
+
`);return!1}if(!await A0(500)){try{L0(Y2)}catch{}try{L0(Q$)}catch{}try{L0(R0)}catch{}return!1}let Z=await V6(1500);try{L0(Y2)}catch{}try{L0(Q$)}catch{}try{L0(R0)}catch{}if(Z)process.stderr.write(`[greedysearch] Killed Chrome on port ${n}.
|
|
299
|
+
`);return Z}async function Y6(){let Z=G2()?X6:J6;if(Z<=0)return!1;if(!H2(Q$))return f$(),!1;try{let X=Number.parseInt(V1(Q$,"utf8").trim(),10);if(!X)return!1;if((Date.now()-X)/60000>=Z)return O2()}catch{}return!1}async function M2(){let Z=(await y(["list"])).split(`
|
|
300
|
+
`)[0];if(!Z)throw Error("No Chrome tabs found");return Z.slice(0,8)}async function T0($="about:blank"){let Z=await M2(),X=new URL($).hostname;if(X==="copilot.microsoft.com"||X==="www.perplexity.ai"||X==="perplexity.ai"||X.endsWith(".perplexity.ai")){let V=await y(["evalraw",Z,"Target.createTarget",JSON.stringify({url:"about:blank"})]),{targetId:j}=JSON.parse(V),Y=j.slice(0,8);if(await y(["list"]).catch(()=>null),X==="copilot.microsoft.com")await t$(Y);else t$(Y).catch(()=>{});return await y(["list"]).catch(()=>null),j}let W=await y(["evalraw",Z,"Target.createTarget",JSON.stringify({url:$})]),{targetId:K}=JSON.parse(W);return await y(["list"]).catch(()=>null),K}async function I0($){try{let Z=await M2();await y(["evalraw",Z,"Target.closeTarget",JSON.stringify({targetId:$})])}catch{}}async function x$($=[]){if(await Promise.all($.filter(Boolean).map((Z)=>I0(Z).catch(()=>{}))),$.length>0)await y(["list"]).catch(()=>null)}function A0($=3000){return new Promise((Z)=>{let X=j1.get(`http://localhost:${n}/json/version`,(J)=>{J.resume(),Z(J.statusCode===200)});X.on("error",()=>Z(!1)),X.setTimeout($,()=>{X.destroy(),Z(!1)})})}async function Q2($=3000,Z=200){let X=Date.now()+$;while(Date.now()<X){if(!await A0(300))return!0;await new Promise((J)=>setTimeout(J,Z))}return!await A0(300)}async function v$(){let $=`${W$}.lock`,Z=`${W$}.tmp`,X=5000,J=1000,W=await new Promise((K)=>{let V=Date.now(),j=()=>{try{let Y=JSON.stringify({pid:process.pid,ts:Date.now()});q$($,Y,{encoding:"utf8",flag:"wx"}),K(!0)}catch(Y){if(Y?.code!=="EEXIST"){if(Date.now()-V<1000)setTimeout(j,50);else K(!1);return}try{let Q=V1($,"utf8").trim(),H=Q.startsWith("{")?JSON.parse(Q):{ts:Number(Q)},B=Number(H?.ts)||0;if(B>0&&Date.now()-B>5000)try{L0($)}catch{}if(Date.now()-V<1000)setTimeout(j,50);else K(!1)}catch{if(Date.now()-V<1000)setTimeout(j,50);else K(!1)}}};j()});try{let K=await new Promise((Y,Q)=>{let H=j1.get(`http://localhost:${n}/json/version`,(B)=>{let N="";B.on("data",(G)=>N+=G),B.on("end",()=>Y(N))});H.on("error",Q),H.setTimeout(3000,()=>{H.destroy(),Q(Error("timeout"))})}),{webSocketDebuggerUrl:V}=JSON.parse(K),j=new URL(V).pathname;if(W){q$(Z,`${n}
|
|
301
|
+
${j}`,"utf8");try{L0(W$)}catch{}e8(Z,W$)}}catch{}finally{if(W)try{L0($)}catch{}}}async function H$(){if(process.env.GREEDY_SEARCH_RESEARCH_CHILD&&await A0()){await v$();try{let K=Y$();if(K)I$(K),W1(K)}catch{}return}K2();let $=await Y6(),Z=$?!1:await A0();if(!Z&&!$)await new Promise((K)=>setTimeout(K,500)),Z=await A0();let X=!1;if(Z){let K=G2(),V=process.env.GREEDY_SEARCH_VISIBLE==="1";if(!V&&!K)process.stderr.write(`[greedysearch] Visible Chrome detected — switching to headless mode...
|
|
302
|
+
`),await m0(),await Q2(),X=!0;else if(V&&K)process.stderr.write(`[greedysearch] Headless Chrome detected — switching to visible mode...
|
|
303
|
+
`),await m0(),await Q2(),X=!0}if(X?!1:await A0()){await v$();try{let K=Y$();if(K)I$(K),W1(K)}catch{}return}let W=V2();if(!W.acquired){let K=Date.now()+12000,V=!1;while(Date.now()<K){if(V=await A0(500),V)break;await new Promise((j)=>setTimeout(j,250))}if(V){await v$();return}}try{if(await A0(1000)){await v$();return}process.stderr.write(`GreedySearch Chrome not running on port ${n} — auto-launching...
|
|
304
|
+
`);let V=[$6(Z6,"..","..","bin","launch.mjs")];if(process.env.GREEDY_SEARCH_VISIBLE!=="1")V.push("--headless");await new Promise((j,Y)=>{r8(H0(),V,{stdio:["ignore",process.stderr,process.stderr]}).on("close",(H)=>H===0?j():Y(Error("launch.mjs failed")))})}finally{W.release()}}var Z6,Y2,Q$,X6,J6,m0,y;var Y1=V0(()=>{x0();r$();w$();n1();D0();j2();Z6=import.meta.dirname||new URL(".",import.meta.url).pathname.replace(/^\/([A-Z]:)/,"$1"),Y2=_$,Q$=k$,X6=Number.parseInt(process.env.GREEDY_SEARCH_IDLE_TIMEOUT_MINUTES||"5",10)||5,J6=Number.parseInt(process.env.GREEDY_SEARCH_VISIBLE_IDLE_TIMEOUT_MINUTES||"60",10)||60;m0=O2;y=S0});async function O6(){if(g$)return g$;let[{Readability:$},{JSDOM:Z},{default:X}]=await Promise.all([import("@mozilla/readability"),import("jsdom"),import("turndown")]),J=new X({headingStyle:"atx",bulletListMarker:"-",codeBlockStyle:"fenced"});return J.addRule("removeDataUrls",{filter:(W)=>W.tagName==="IMG"&&W.getAttribute("src")?.startsWith("data:"),replacement:()=>""}),g$={Readability:$,JSDOM:Z,turndown:J},g$}function U6($){if(!$||$.includes(":"))return null;let Z=$.split(".");if(Z.length<1||Z.length>4)return null;if(!Z.every((W)=>z6.test(W)))return null;let X=Z.map((W)=>{if(/^0x/i.test(W))return parseInt(W,16);if(/^0[0-7]+$/.test(W))return parseInt(W,8);return parseInt(W,10)});if(X.some((W)=>!Number.isFinite(W)||W<0))return null;let J;if(X.length===1){if(X[0]>4294967295)return null;J=[X[0]>>>24&255,X[0]>>>16&255,X[0]>>>8&255,X[0]&255]}else if(X.length===2){if(X[0]>255||X[1]>16777215)return null;J=[X[0],X[1]>>>16&255,X[1]>>>8&255,X[1]&255]}else if(X.length===3){if(X[0]>255||X[1]>255||X[2]>65535)return null;J=[X[0],X[1],X[2]>>>8&255,X[2]&255]}else{if(X.some((W)=>W>255))return null;J=X}return J.join(".")}function F6($){let Z=$.match(M6);if(Z)return`${Z[1]}.${Z[2]}.${Z[3]}.${Z[4]}`;let X=$.match(D6);if(X){let J=parseInt(X[1],16),W=parseInt(X[2],16);if(J>65535||W>65535)return null;return[J>>>8&255,J&255,W>>>8&255,W&255].join(".")}return null}function z2($){return P2.some((Z)=>Z.test($))}function _2($={}){return{...w2,...$}}function y$($){try{if(typeof $!=="string"||!$.trim())return{blocked:!0,reason:"URL must be a non-empty string"};let Z=new URL($);if(Z.protocol!=="http:"&&Z.protocol!=="https:")return{blocked:!0,reason:`Protocol not allowed: ${Z.protocol}`};let X=Z.hostname.toLowerCase();for(let W of P2)if(W.test(X))return{blocked:!0,reason:`Private/internal address: ${X}`};if(X.startsWith("[")&&X.endsWith("]")){let W=X.slice(1,-1),K=F6(W);if(K&&z2(K))return{blocked:!0,reason:`Private/internal address: ${X} (maps to ${K})`}}let J=U6(X);if(J&&z2(J))return{blocked:!0,reason:`Private/internal address: ${X} (normalizes to ${J})`};return{blocked:!1}}catch(Z){return{blocked:!0,reason:`Invalid URL: ${Z.message}`}}}function w6($){try{let Z=new URL($);if(!(Z.hostname==="github.com"||Z.hostname.endsWith(".github.com")))return $;let X=Z.pathname.split("/").filter(Boolean);if(X.length<5)return $;let[J,W,K,V,...j]=X;if(K!=="blob")return $;let Y=j.join("/");return`https://raw.githubusercontent.com/${J}/${W}/${V}/${Y}`}catch{return $}}async function k2($,Z={}){let X=y$($);if(X.blocked)return{ok:!1,url:$,finalUrl:$,status:403,error:`Blocked: ${X.reason}`,needsBrowser:!1};let J=$;if($=w6($),$!==J)console.error(`[fetcher] Rewrote GitHub URL: ${J.slice(0,60)}... → raw.githubusercontent.com`);let{timeoutMs:W=15000,userAgent:K,signal:V}=Z,j=new AbortController,Y=setTimeout(()=>j.abort(),W);if(V)V.addEventListener("abort",()=>j.abort(),{once:!0});try{let Q=await fetch($,{method:"GET",headers:{...w2,"user-agent":K||F2},redirect:"follow",signal:j.signal});clearTimeout(Y);let H=Q.headers.get("content-type")||"",B=Q.url,N=Q.headers.get("last-modified")||"",G=y$(B);if(G.blocked)return{ok:!1,url:$,finalUrl:B,status:Q.status,error:`Blocked: ${G.reason}`,needsBrowser:!1};let O=!1;try{O=new URL(B).hostname.toLowerCase()==="raw.githubusercontent.com"}catch{}if(H.includes("text/plain")&&O){let P=await Q.text();return{ok:!0,url:J,finalUrl:B,status:Q.status,title:B.split("/").pop()||"GitHub File",byline:"",siteName:"GitHub",lang:"",publishedTime:N,lastModified:N,markdown:P,contentLength:P.length,excerpt:P.slice(0,300).replaceAll(/\n/g," "),needsBrowser:!1}}if(!H.includes("text/html")&&!H.includes("application/xhtml"))return{ok:!1,url:$,finalUrl:B,status:Q.status,error:`Unsupported content type: ${H}`,needsBrowser:!1};let M=await Q.text(),D=Q1(Q.status,M,B,$);if(D.blocked)return{ok:!1,url:$,finalUrl:B,status:Q.status,error:`Blocked: ${D.reason}`,needsBrowser:!0};let z=await H1(M,B),F=B1(z);if(!F.ok)return{ok:!1,url:$,finalUrl:B,status:Q.status,error:`Low quality content: ${F.reason}`,needsBrowser:!0};return{ok:!0,url:$,finalUrl:B,status:Q.status,title:z.title,byline:z.byline,siteName:z.siteName,lang:z.lang,publishedTime:z.publishedTime||N,lastModified:N,markdown:z.markdown,excerpt:z.excerpt,contentLength:z.markdown.length,needsBrowser:!1}}catch(Q){clearTimeout(Y);let H=A6(Q);return{ok:!1,url:$,finalUrl:$,status:0,error:Q.message,needsBrowser:H}}}function Q1($,Z,X,J){let W=Z.match(/<title[^>]*>([^<]*)<\/title>/i)?.[1]?.toLowerCase()||"",K=Z.slice(0,30000).toLowerCase(),V=`${W} ${K}`;if($===403||$===429||$===503)return{blocked:!0,reason:`HTTP ${$}`};let j=[{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 Q of j)if(Q.pattern.test(V))return{blocked:!0,reason:Q.reason};let Y=L6(J,X,Z);if(Y)return{blocked:!0,reason:Y};return{blocked:!1}}function L6($,Z,X){try{let J=new URL($),W=new URL(Z);if(J.hostname.toLowerCase()===W.hostname.toLowerCase())return;let K=W.hostname.toLowerCase();if(P6.some((j)=>K===j||K.endsWith(`.${j}`)))return`redirected to login (${W.hostname})`;if(_6.some((j)=>K.startsWith(j)))return`redirected to login (${W.hostname})`;let V=X.slice(0,20000).toLowerCase();if(k6.some((j)=>V.includes(j)))return`redirected to login page (${W.hostname})`}catch{}return}function A6($){let Z=$.message.toLowerCase();return Z.includes("fetch failed")||Z.includes("unable to verify")||Z.includes("certificate")||Z.includes("timeout")}function U2($){let Z=['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 X of Z){let J=$.querySelector(X),W=J?.getAttribute("content")||J?.getAttribute("datetime")||"";if(W)return W}return""}async function H1($,Z){let{Readability:X,JSDOM:J,turndown:W}=await O6(),K=new J($,{url:Z});try{let V=K.window.document,Y=new X(V).parse();if(Y&&Y.content){let B=W.turndown(Y.content).replaceAll(/\n{3,}/g,`
|
|
229
305
|
|
|
230
|
-
`).trim(),
|
|
306
|
+
`).trim(),N=Y.publishedTime||U2(V)||"";return{title:Y.title||V.title||Z,byline:Y.byline||"",siteName:Y.siteName||"",lang:Y.lang||"",publishedTime:N,markdown:B,excerpt:B.slice(0,300).replaceAll(/\n/g," ")}}let Q=V.body;if(Q){let H=Q.cloneNode(!0);H.querySelectorAll("script, style, nav, footer, header, aside").forEach((G)=>G.remove());let N=(H.textContent||"").replaceAll(/\s+/g," ").trim();return{title:V.title||Z,byline:"",siteName:"",lang:"",publishedTime:U2(V),markdown:N,excerpt:N.slice(0,300)}}return{title:Z,byline:"",siteName:"",lang:"",publishedTime:"",markdown:"",excerpt:""}}finally{K.window.close()}}function B1($){let Z=$.markdown.trim().toLowerCase(),X=($.title||"").toLowerCase();if($.markdown.trim().length<100)return{ok:!1,reason:"content too short (< 100 chars)"};let J=Z.toLowerCase(),W=[{check:()=>J.includes("loading")&&J.includes("please wait"),desc:"loading page"},{check:()=>J.includes("please ensure javascript is enabled"),desc:"requires javascript"},{check:()=>J.includes("enable javascript to view"),desc:"requires javascript"},{check:()=>J.includes("just a moment"),desc:"cloudflare challenge detected in content"},{check:()=>J.includes("verify you are human"),desc:"human verification"},{check:()=>J.includes("captcha required"),desc:"captcha in extracted content"},{check:()=>J.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(Z),desc:"login form only"}];for(let{check:K,desc:V}of W)if(K())return{ok:!1,reason:V};if(X.includes("just a moment")||X.includes("checking your browser"))return{ok:!1,reason:"cloudflare challenge page detected in title"};return{ok:!0}}var g$=null,F2="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",w2,P2,M6,D6,z6,P6,_6,k6;var L2=V0(()=>{w2={"user-agent":F2,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"},P2=[/^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],M6=/^::ffff:(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/i,D6=/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i,z6=/^(?:0x[0-9a-f]+|0[0-7]*|[1-9][0-9]*)$/i;P6=["accounts.google.com","login.microsoftonline.com","login.live.com","auth0.com","okta.com","auth.mozilla.auth0.com","id.atlassian.com"],_6=["login.","signin.","auth.","sso.","accounts.","idp."],k6=["sign in to continue","log in to continue","authentication required","create an account to continue","subscribe to continue reading","members only"]});var C2={};s$(C2,{parseGitHubUrl:()=>B$,fetchGitHubContent:()=>G1});function B$($){try{let Z=new URL($);if(!(Z.hostname==="github.com"||Z.hostname.endsWith(".github.com")))return null;let X=Z.pathname.split("/").filter(Boolean);if(X.length<2)return null;let[J,W]=X;if(X.length===2)return{owner:J,repo:W,type:"root"};if(X.length>=4&&(X[2]==="blob"||X[2]==="tree")){let K=X[2],V=X[3],j=X.slice(4).join("/");return{owner:J,repo:W,type:K,ref:V,path:j}}return null}catch{return null}}async function O0($,Z=1e4){let X=new AbortController,J=setTimeout(()=>X.abort(),Z);try{let W=await fetch(`https://api.github.com${$}`,{headers:T2,signal:X.signal});if(clearTimeout(J),!W.ok)throw Error(`GitHub API ${W.status}: ${$}`);return await W.json()}catch(W){throw clearTimeout(J),W}}async function T6($,Z){try{let X=await O0(`/repos/${$}/${Z}/readme`);if(X.content&&X.encoding==="base64")return Buffer.from(X.content,"base64").toString("utf8");return""}catch{return""}}async function A2($,Z,X="HEAD",J="",W){try{let K;if(X==="HEAD")if(W)K=await O0(`/repos/${$}/${Z}/git/ref/heads/${W}`).catch(()=>null);else K=await Promise.any([O0(`/repos/${$}/${Z}/git/ref/heads/main`),O0(`/repos/${$}/${Z}/git/ref/heads/master`)]).catch(()=>null);else K=await O0(`/repos/${$}/${Z}/git/ref/heads/${X}`).catch(()=>O0(`/repos/${$}/${Z}/git/ref/heads/master`).catch(()=>null));if(!K?.object?.sha)return[];let j=(await O0(`/repos/${$}/${Z}/git/commits/${K.object.sha}`)).tree.sha,Q=(await O0(`/repos/${$}/${Z}/git/trees/${j}`)).tree||[];if(J)Q=Q.filter((H)=>H.path.startsWith(J));return Q.slice(0,50).map((H)=>({path:H.path,type:H.type==="tree"?"dir":"file",size:H.size}))}catch{return[]}}async function C6($,Z,X,J,W=1e4,K){let V=async(Y)=>{let Q=new AbortController,H=setTimeout(()=>Q.abort(),W);try{let B=await fetch(Y,{headers:{"user-agent":T2["user-agent"]},signal:Q.signal});if(clearTimeout(H),B.ok)return await B.text();throw Error("not ok")}catch{throw clearTimeout(H),Error("failed")}};if(!X||X==="HEAD"){if(K)try{return await V(`https://raw.githubusercontent.com/${$}/${Z}/${K}/${J}`)}catch{return null}try{return await Promise.any([V(`https://raw.githubusercontent.com/${$}/${Z}/main/${J}`),V(`https://raw.githubusercontent.com/${$}/${Z}/master/${J}`)])}catch{return null}}let j=[`https://raw.githubusercontent.com/${$}/${Z}/${X}/${J}`,`https://raw.githubusercontent.com/${$}/${Z}/master/${J}`];for(let Y of j)try{return await V(Y)}catch{}return null}async function G1($){let Z=B$($);if(!Z)return{ok:!1,error:"Not a valid GitHub URL"};let{owner:X,repo:J,type:W,ref:K,path:V}=Z;try{if(W==="root"||W==="tree"&&!V){let j=await O0(`/repos/${X}/${J}`),[Y,Q]=await Promise.allSettled([T6(X,J),A2(X,J,K||"HEAD","",j.default_branch)]),H=Y.status==="fulfilled"?Y.value:"",B=Q.status==="fulfilled"?Q.value:[],N=j?.description?`
|
|
231
307
|
|
|
232
|
-
> ${
|
|
308
|
+
> ${j.description}`:"",G=j?.stargazers_count==null?"":` ⭐ ${j.stargazers_count}`,O=j?.language?` · ${j.language}`:"",M=`# ${X}/${J}${G}${O}${N}
|
|
233
309
|
|
|
234
310
|
`;if(H)M+=H.slice(0,6000);else M+=`[No README found]
|
|
235
311
|
|
|
236
312
|
Files:
|
|
237
|
-
${
|
|
238
|
-
`)}`;return{ok:!0,title:`${X}/${J}`,content:M,tree:
|
|
313
|
+
${B.map((D)=>` ${D.type==="dir"?"\uD83D\uDCC1":"\uD83D\uDCC4"} ${D.path}`).join(`
|
|
314
|
+
`)}`;return{ok:!0,title:`${X}/${J}`,content:M,tree:B.slice(0,30)}}if(W==="blob"&&V){let j;if(!K||K==="HEAD")try{j=(await O0(`/repos/${X}/${J}`)).default_branch}catch{j=void 0}let Y=await C6(X,J,K,V,1e4,j);if(Y===null)return{ok:!1,error:`File not found: ${V}`};return{ok:!0,title:`${X}/${J}: ${V}`,content:Y}}if(W==="tree"&&V){let j;if(!K||K==="HEAD")try{j=(await O0(`/repos/${X}/${J}`)).default_branch}catch{j=void 0}let Y=await A2(X,J,K||"HEAD",V,j),Q=Y.map((H)=>` ${H.type==="dir"?"\uD83D\uDCC1":"\uD83D\uDCC4"} ${H.path}`).join(`
|
|
239
315
|
`);return{ok:!0,title:`${X}/${J}/${V}`,content:`[Directory: ${V}]
|
|
240
316
|
|
|
241
317
|
Files:
|
|
242
|
-
${
|
|
318
|
+
${Q}`,tree:Y}}return{ok:!1,error:"Unsupported GitHub URL type"}}catch(j){return{ok:!1,error:j.message}}}var T2;var N1=V0(()=>{T2={"user-agent":"GreedySearch/1.0",accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});function I2($){try{let Z=new URL($),X=Z.hostname.toLowerCase();if(!(X==="reddit.com"||X.endsWith(".reddit.com")))return null;let J=Z.pathname;if(J.match(/^\/(u|user)\/[^/]+\/?$/i))return{type:"user",cleanUrl:R2($)};if(J.match(/^\/r\/[^/]+\/comments\/[^/]+/i))return{type:"post",cleanUrl:R2($)};return null}catch{return null}}function R2($){try{let Z=new URL($);return`${Z.protocol}//${Z.hostname}${Z.pathname}`}catch{return $}}async function v2($,Z=8000){let X=Date.now();try{let J=$.replace(/\/+$/,"")+".json",W=new AbortController,K=setTimeout(()=>W.abort(),15000),V=await fetch(J,{headers:R6,signal:W.signal});if(clearTimeout(K),!V.ok)throw Error(`Reddit API ${V.status}`);let j=await V.json();if(!Array.isArray(j)||j.length<1)throw Error("Invalid Reddit API response structure");let Y=j[0],Q=j[1],H=Y?.data?.children?.[0]?.data;if(!H)throw Error("No post data in Reddit response");let B=I6(H,Q,Z);return{ok:!0,url:$,finalUrl:$,status:200,contentType:"text/markdown",lastModified:"",title:H.title||"Reddit Post",byline:`u/${H.author}`,siteName:`r/${H.subreddit}`,lang:"en",publishedTime:new Date(H.created_utc*1000).toISOString(),excerpt:H.selftext?.slice(0,300).replace(/\n/g," ")||"",markdown:B,contentLength:B.length,needsBrowser:!1,duration:Date.now()-X}}catch(J){return{ok:!1,url:$,finalUrl:$,status:0,error:`Reddit fetch failed: ${J.message}`,needsBrowser:!1,duration:Date.now()-X}}}function I6($,Z,X){let J="";if(J+=`# ${$.title}
|
|
243
319
|
|
|
244
320
|
`,J+=`**Subreddit:** r/${$.subreddit} | **Author:** u/${$.author} | **Score:** ${$.score}
|
|
245
321
|
|
|
@@ -253,27 +329,27 @@ ${j}`,tree:Y}}return{ok:!1,error:"Unsupported GitHub URL type"}}catch(Y){return{
|
|
|
253
329
|
|
|
254
330
|
## Comments
|
|
255
331
|
|
|
256
|
-
`;let W=Z.data.children.filter((K)=>K.kind==="t1").slice(0,10);for(let K of W)J+=
|
|
332
|
+
`;let W=Z.data.children.filter((K)=>K.kind==="t1").slice(0,10);for(let K of W)J+=q2(K.data,0),J+=`
|
|
257
333
|
`}if(J.length>X)J=J.slice(0,X).trim()+`
|
|
258
334
|
|
|
259
|
-
... (truncated)`;return J}function
|
|
335
|
+
... (truncated)`;return J}function q2($,Z){if(!$||$.body==="[deleted]"||$.body==="[removed]")return"";let X="> ".repeat(Z),J="";if(J+=`${X}**u/${$.author}** (${$.score} pts)
|
|
260
336
|
`,J+=`${X}${$.body.replaceAll(`
|
|
261
337
|
`,`
|
|
262
338
|
`+X)}
|
|
263
339
|
`,Z<3&&$.replies?.data?.children){let W=$.replies.data.children.filter((K)=>K.kind==="t1");for(let K of W.slice(0,5))J+=`
|
|
264
|
-
`+
|
|
340
|
+
`+q2(K.data,Z+1)}return J}var R6;var E2=V0(()=>{R6={"user-agent":"GreedySearch/1.0 (Research Bot)",accept:"application/json"}});function d0($,Z=8000){if(!$||$.length<=Z)return $;let X=`
|
|
265
341
|
|
|
266
342
|
[...content trimmed...]
|
|
267
343
|
|
|
268
344
|
`,J=Z-X.length,W=Math.floor(J*0.75),K=J-W,V=W;while(V>W-100&&$[V]!==`
|
|
269
|
-
`)V--;if(V<=W-100)V=W;let
|
|
270
|
-
`)
|
|
345
|
+
`)V--;if(V<=W-100)V=W;let j=$.length-K;while(j<$.length-K+100&&$[j]!==`
|
|
346
|
+
`)j++;if(j>=$.length-K+100)j=$.length-K;let Y=$.slice(0,V).trimEnd(),Q=$.slice(j).trimStart();return`${Y}${X}${Q}`}function v6(){if(typeof globalThis.DOMMatrix>"u")globalThis.DOMMatrix=class{constructor(Z=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(Z=void 0,X=0,J=0){this.data=Z,this.width=X,this.height=J}};if(typeof globalThis.Path2D>"u")globalThis.Path2D=class{constructor(Z=void 0){}}}async function q6(){v6();let $=await import("pdf-parse"),Z=$.PDFParse??$.default;if(!Z)throw Error("pdf-parse did not export PDFParse");return Z}async function f2($,Z){try{let J=new(await q6())({data:new Uint8Array($)});await J.load();let W=await J.getText(),K=W.text?.trim();if(!K)return null;return{title:new URL(Z).pathname.split("/").pop()||"Document.pdf",content:`## PDF Content (${W.total} pages)
|
|
271
347
|
|
|
272
|
-
${K}`,pages:W.total}}catch(X){return{error:X.message||String(X)}}}function b($="",Z=240){let X=String($).replaceAll(/\s+/g," ").trim();if(X.length<=Z)return X;let J=X.slice(0,Z),W=J.lastIndexOf(" ");return W>0?`${J.slice(0,W)}...`:`${J}...`}function j1($=""){let Z=b($,180);if(!Z)return"";if(/^https?:\/\//i.test(Z))return"";let X=Z.split(/\s+/).filter(Boolean).length,J=/[A-Z]/.test(Z),W=/\d/.test(Z);return Z===Z.toLowerCase()&&X<=4&&!J&&!W?"":Z}function Q1($="",Z=""){let X=j1($),J=j1(Z);if(!J)return X;if(!X)return J;let W=/^https?:\/\//i.test(X),K=/^https?:\/\//i.test(J);if(W&&!K)return J;if(!W&&K)return X;return J.length>X.length?J:X}function e($){if(!$)return null;try{let Z=new URL($);if(!["http:","https:"].includes(Z.protocol))return null;if(Z.hash="",Z.hostname=Z.hostname.toLowerCase(),Z.protocol==="https:"&&Z.port==="443"||Z.protocol==="http:"&&Z.port==="80")Z.port="";for(let W of[...Z.searchParams.keys()]){let K=W.toLowerCase();if(R6.includes(K)||K.startsWith("utm_"))Z.searchParams.delete(W)}Z.searchParams.sort();let X=Z.pathname.replace(/\/{1,10}$/,"")||"/";Z.pathname=X;let J=Z.toString();return X==="/"?J.replace(/\/$/,""):J}catch{return null}}function E6($){try{return new URL($).hostname.toLowerCase().replace(/^www\./,"")}catch{return""}}function Z$($,Z){return Z.some((X)=>$===X||$.endsWith(`.${X}`))}function B1($,Z="",X=""){let J=Z.toLowerCase(),W=X.toLowerCase();if($==="github.com"||$==="gitlab.com")return"repo";if($==="arxiv.org"||$==="doi.org"||$==="semanticscholar.org"||$.endsWith(".semanticscholar.org")||W.includes("/paper/")||W.includes("/pdf/"))return"academic";if(Z$($,F2))return"social";if(Z$($,I6))return"community";if(Z$($,b6))return"news";if($.startsWith("docs.")||$.startsWith("developer.")||$.startsWith("developers.")||$.startsWith("api.")||J.includes("documentation")||J.includes("docs")||J.includes("reference")||W.includes("/docs/")||W.includes("/reference/")||W.includes("/api/"))return"official-docs";if($.startsWith("blog.")||W.includes("/blog/"))return"maintainer-blog";return"website"}function q6($){switch($){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 v6($){let Z=Object.values($.perEngine||{}).map((X)=>X?.rank||99);return Z.length?Math.min(...Z):99}function w0($){return $.smartScore*3+$.engineCount*5+q6($.sourceType)*2+Math.max(0,7-v6($))}function x6($){let Z=$.toLowerCase(),X=[];if(Z.includes("openai")||Z.includes("gpt")||Z.includes("chatgpt"))X.push("openai.com","platform.openai.com","help.openai.com");if(Z.includes("anthropic")||Z.includes("claude"))X.push("anthropic.com","docs.anthropic.com");if(Z.includes("bun"))X.push("bun.sh","bun.com");if(Z.includes("next.js")||Z.includes("nextjs"))X.push("nextjs.org","vercel.com");if(Z.includes("playwright"))X.push("playwright.dev");if(Z.includes("supabase"))X.push("supabase.com","supabase.io");if(Z.includes("prisma"))X.push("prisma.io");if(Z.includes("tailwind"))X.push("tailwindcss.com");if(Z.includes("vite"))X.push("vitejs.dev","vite.dev");if(Z.includes("astro"))X.push("astro.build");if(Z.includes("svelte"))X.push("svelte.dev");if(Z.includes("solid"))X.push("solidjs.com");if(Z.includes("vue")||Z.includes("nuxt"))X.push("vuejs.org","nuxt.com");if(Z.includes("react")||Z.includes("react native"))X.push("react.dev","reactnative.dev");if(Z.includes("angular"))X.push("angular.io","angular.dev");if(Z.includes("node.js")||Z.includes("nodejs"))X.push("nodejs.org","nodejs.dev","npmjs.com");if(/\bgo\b/.test(Z)||Z.includes("golang"))X.push("go.dev","golang.org","pkg.go.dev");if(Z.includes("deno"))X.push("deno.land","deno.com");if(Z.includes("fresh"))X.push("fresh.deno.dev");if(Z.includes("typescript")||Z.includes("ts"))X.push("typescriptlang.org");if(Z.includes("python"))X.push("python.org","docs.python.org");if(Z.includes("rust"))X.push("rust-lang.org","docs.rs","crates.io");if(Z.includes("zig"))X.push("ziglang.org");if(Z.includes("docker"))X.push("docker.com","docs.docker.com","hub.docker.com");if(Z.includes("kubernetes")||Z.includes("k8s"))X.push("kubernetes.io","k8s.io");if(Z.includes("postgres")||Z.includes("postgresql"))X.push("postgresql.org","neon.tech","supabase.com");if(Z.includes("redis"))X.push("redis.io");if(Z.includes("sqlite"))X.push("sqlite.org");if(Z.includes("cloudflare"))X.push("developers.cloudflare.com","cloudflare.com");if(Z.includes("vercel"))X.push("vercel.com","nextjs.org");if(Z.includes("netlify"))X.push("netlify.com","docs.netlify.com");if(Z.includes("stripe"))X.push("stripe.com","docs.stripe.com");if(Z.includes("github"))X.push("github.com","docs.github.com");if(Z.includes("gitlab"))X.push("gitlab.com","docs.gitlab.com");if(Z.includes("aws"))X.push("aws.amazon.com","docs.aws.amazon.com");if(Z.includes("azure"))X.push("azure.microsoft.com","learn.microsoft.com");if(Z.includes("gcp")||Z.includes("google cloud"))X.push("cloud.google.com","developers.google.com");if(Z.includes("gemini")||Z.includes("google ai"))X.push("ai.google.dev","developers.google.com");for(let J of F2){let W=J.replace(/\.com$/,"");if(Z.includes(W))X.push(J)}return[...new Set(X)]}function P2($,Z){return $===Z||$.endsWith(`.${Z}`)}function m0($,Z=""){let X=new Map,J=Object.keys($||{}).filter((Q)=>!Q.startsWith("_")),W=x6(Z);for(let Q of J){let B=$[Q];if(!B?.sources)continue;for(let H=0;H<B.sources.length;H++){let G=B.sources[H],O=e(G.url);if(!O||O.length<10)continue;let z=j1(G.title||""),D=E6(O),M=B1(D,z,O),k=0;if(W.some((x)=>P2(D,x)))k+=10;if(M==="official-docs")k+=3;let E=O.toLowerCase();if(/\/docs\/|\/documentation\/|\.dev\/|\/api\/|\/reference\//.test(E))k+=2;let P=W.some((x)=>P2(D,x));if(M==="social"&&!P)k-=20;if(W.length>0){if(Z$(D,f6))k-=3;else if(M==="community"&&!Z$(D,["stackoverflow.com","stackexchange.com"]))k-=1}let T=X.get(O)||{id:"",canonicalUrl:O,displayUrl:G.url||O,domain:D,title:"",engines:[],engineCount:0,perEngine:{},sourceType:M,isOfficial:M==="official-docs",smartScore:0};if(T.title=Q1(T.title,z),T.displayUrl=T.displayUrl||G.url||O,T.sourceType=T.sourceType||M,T.isOfficial=T.isOfficial||M==="official-docs",T.smartScore=Math.max(T.smartScore,k),!T.engines.includes(Q))T.engines.push(Q);T.perEngine[Q]={rank:H+1,title:Q1(T.perEngine[Q]?.title||"",z)},X.set(O,T)}}let K=Array.from(X.values()).map((Q)=>({...Q,engineCount:Q.engines.length})),V=K.filter((Q)=>Q.sourceType!=="social"),Y=K.filter((Q)=>Q.sourceType==="social");return V.sort((Q,B)=>{let H=w0(B)-w0(Q);if(H!==0)return H;return Q.domain.localeCompare(B.domain)}),Y.sort((Q,B)=>{let H=w0(B)-w0(Q);if(H!==0)return H;return Q.domain.localeCompare(B.domain)}),[...V,...Y].slice(0,12).map((Q,B)=>({...Q,id:`S${B+1}`,title:Q.title||Q.domain||Q.canonicalUrl}))}function w$($,Z){let X=new Map(Z.map((J)=>[J.id,J]));return $.map((J)=>{let W=X.get(J.id);if(!W)return J;let K=Q1(J.title,W.title||"");return{...J,title:K||J.title,fetch:{attempted:!0,ok:!W.error&&W.contentChars>100,status:W.status||null,finalUrl:W.finalUrl||W.url||J.canonicalUrl,contentType:W.contentType||"",lastModified:W.lastModified||"",publishedTime:W.publishedTime||"",byline:W.byline||"",siteName:W.siteName||"",lang:W.lang||"",title:W.title||"",snippet:W.snippet||"",contentChars:W.contentChars||0,source:W.source||"unknown",duration:W.duration||0,error:W.error||""}}})}var R6,I6,b6,F2,f6;var d0=l(()=>{R6=["fbclid","gclid","ref","ref_src","ref_url","source","utm_campaign","utm_content","utm_medium","utm_source","utm_term"],I6=["dev.to","hashnode.com","medium.com","reddit.com","stackoverflow.com","stackexchange.com","substack.com"],b6=["arstechnica.com","techcrunch.com","theverge.com","venturebeat.com","wired.com","zdnet.com"],F2=["facebook.com","instagram.com","linkedin.com","pinterest.com","tiktok.com","twitter.com","x.com"];f6=["reddit.com","news.ycombinator.com","lobste.rs"]});var w2={};u0(w2,{fetchTopSource:()=>X$,fetchSourceContent:()=>T2,fetchMultipleSources:()=>H1});async function S6($,Z,X=8000){let J=Date.now();try{let K=(await q(["evalraw",$,"Page.getFrameTree","{}"]).then((z)=>JSON.parse(z)).catch(()=>null))?.frameTree?.frame?.id||void 0,V=await q(["evalraw",$,"Network.loadNetworkResource",JSON.stringify({frameId:K,url:Z,options:{disableCache:!0,includeCredentials:!1}})],20000),j=JSON.parse(V).resource;if(!j?.success||!j.httpStatusCode)return{url:Z,error:j?.netErrorName||j?.netError||"loadNetworkResource failed",source:"chrome",duration:Date.now()-J,needsFallback:!0};let Q="";if(j.stream)try{let z=await q(["evalraw",$,"IO.read",JSON.stringify({handle:j.stream})],1e4);Q=JSON.parse(z).data||"",await q(["evalraw",$,"IO.close",JSON.stringify({handle:j.stream})]).catch(()=>{})}catch{}if(!Q||Q.length<100)return{url:Z,error:"Empty response body from Network.loadNetworkResource",source:"chrome",duration:Date.now()-J,needsFallback:!0};let B=P$(j.httpStatusCode,Q,Z,Z);if(B.blocked)return{url:Z,status:j.httpStatusCode,error:`Blocked: ${B.reason}`,source:"chrome",duration:Date.now()-J,needsBrowser:!0};let H=F$(Q,Z),G=L$(H);if(!G.ok)return{url:Z,status:j.httpStatusCode,error:`Low quality: ${G.reason}`,source:"chrome",duration:Date.now()-J,needsBrowser:!0};let O=N0(H.markdown,X);return{url:Z,finalUrl:Z,status:j.httpStatusCode,contentType:"text/markdown",lastModified:"",publishedTime:H.publishedTime||"",byline:H.byline||"",siteName:H.siteName||"",lang:H.lang||"",title:H.title||Z,snippet:H.excerpt,content:O,contentChars:O.length,source:"chrome",duration:Date.now()-J}}catch(W){return{url:Z,error:W.message,source:"chrome",duration:Date.now()-J,needsFallback:!0}}}function L2($){try{return new URL($).pathname.toLowerCase().endsWith(".pdf")}catch{return!1}}async function g6($,Z=8000){let X=k$($);if(X.blocked)return{url:$,finalUrl:$,status:403,error:`Blocked: ${X.reason}`,source:"pdf-http"};let J=new AbortController,W=setTimeout(()=>J.abort(),20000),K=Date.now();try{let V=await fetch($,{method:"GET",redirect:"follow",signal:J.signal,headers:Z1({accept:"application/pdf,application/octet-stream;q=0.9,*/*;q=0.5"})});clearTimeout(W);let Y=V.headers.get("content-type")||"",j=V.url||$,Q=Number.parseInt(V.headers.get("content-length")||"0",10);if(V.status>=400)return{url:$,finalUrl:j,status:V.status,error:`HTTP ${V.status}`,source:"pdf-http",duration:Date.now()-K};if(!Y.toLowerCase().includes("application/pdf")&&!L2(j))return null;if(Q>31457280)return{url:$,finalUrl:j,status:V.status,error:`PDF too large: ${Q} bytes`,source:"pdf-http",duration:Date.now()-K};let B=Buffer.from(await V.arrayBuffer()),H=await k2(B,j);if(!H||H.error)return{url:$,finalUrl:j,status:V.status,error:H?.error||"PDF text extraction failed",source:"pdf-http",duration:Date.now()-K};let G=N0(H.content,Z);return{url:$,finalUrl:j,status:V.status,contentType:"application/pdf",lastModified:V.headers.get("last-modified")||"",title:H.title,snippet:b(G,320),content:G,contentChars:G.length,pages:H.pages,source:"pdf-http",duration:Date.now()-K}}catch(V){return clearTimeout(W),{url:$,finalUrl:$,error:V.message||String(V),source:"pdf-http",duration:Date.now()-K}}}async function T2($,Z=8000){let X=Date.now();if(L2($)){let K=await g6($,Z);if(K?.content||K?.status===403)return K}if($$($)){let K=$$($);if(K&&(K.type==="root"||K.type==="tree"||K.type==="blob"&&!K.path?.includes("."))){let V=await W1($);if(V.ok){let Y=N0(V.content,Z);return{url:$,finalUrl:$,status:200,contentType:"text/markdown",lastModified:"",title:V.title,snippet:Y.slice(0,320),content:Y,contentChars:Y.length,source:"github-api",...V.tree&&{tree:V.tree},duration:Date.now()-X}}process.stderr.write(`[greedysearch] GitHub API fetch failed, trying HTTP: ${V.error}
|
|
273
|
-
`)}}if(
|
|
274
|
-
`);let K=await
|
|
275
|
-
`)}let W=await
|
|
276
|
-
`),await
|
|
348
|
+
${K}`,pages:W.total}}catch(X){return{error:X.message||String(X)}}}function R($="",Z=240){let X=String($).replaceAll(/\s+/g," ").trim();if(X.length<=Z)return X;let J=X.slice(0,Z),W=J.lastIndexOf(" ");return W>0?`${J.slice(0,W)}...`:`${J}...`}function M1($=""){let Z=R($,180);if(!Z)return"";if(/^https?:\/\//i.test(Z))return"";let X=Z.split(/\s+/).filter(Boolean).length,J=/[A-Z]/.test(Z),W=/\d/.test(Z);return Z===Z.toLowerCase()&&X<=4&&!J&&!W?"":Z}function D1($="",Z=""){let X=M1($),J=M1(Z);if(!J)return X;if(!X)return J;let W=/^https?:\/\//i.test(X),K=/^https?:\/\//i.test(J);if(W&&!K)return J;if(!W&&K)return X;return J.length>X.length?J:X}function e($){if(!$)return null;try{let Z=new URL($);if(!["http:","https:"].includes(Z.protocol))return null;if(Z.hash="",Z.hostname=Z.hostname.toLowerCase(),Z.protocol==="https:"&&Z.port==="443"||Z.protocol==="http:"&&Z.port==="80")Z.port="";for(let W of[...Z.searchParams.keys()]){let K=W.toLowerCase();if(E6.includes(K)||K.startsWith("utm_"))Z.searchParams.delete(W)}Z.searchParams.sort();let X=Z.pathname.replace(/\/{1,10}$/,"")||"/";Z.pathname=X;let J=Z.toString();return X==="/"?J.replace(/\/$/,""):J}catch{return null}}function x6($){try{return new URL($).hostname.toLowerCase().replace(/^www\./,"")}catch{return""}}function G$($,Z){return Z.some((X)=>$===X||$.endsWith(`.${X}`))}function z1($,Z="",X=""){let J=Z.toLowerCase(),W=X.toLowerCase();if($==="github.com"||$==="gitlab.com")return"repo";if($==="arxiv.org"||$==="doi.org"||$==="semanticscholar.org"||$.endsWith(".semanticscholar.org")||W.includes("/paper/")||W.includes("/pdf/"))return"academic";if(G$($,x2))return"social";if(G$($,f6))return"community";if(G$($,b6))return"news";if($.startsWith("docs.")||$.startsWith("developer.")||$.startsWith("developers.")||$.startsWith("api.")||J.includes("documentation")||J.includes("docs")||J.includes("reference")||W.includes("/docs/")||W.includes("/reference/")||W.includes("/api/"))return"official-docs";if($.startsWith("blog.")||W.includes("/blog/"))return"maintainer-blog";return"website"}function S6($){switch($){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 g6($){let Z=Object.values($.perEngine||{}).map((X)=>X?.rank||99);return Z.length?Math.min(...Z):99}function l0($){return $.smartScore*3+$.engineCount*5+S6($.sourceType)*2+Math.max(0,7-g6($))}function h6($){let Z=$.toLowerCase(),X=[];if(Z.includes("openai")||Z.includes("gpt")||Z.includes("chatgpt"))X.push("openai.com","platform.openai.com","help.openai.com");if(Z.includes("anthropic")||Z.includes("claude"))X.push("anthropic.com","docs.anthropic.com");if(Z.includes("bun"))X.push("bun.sh","bun.com");if(Z.includes("next.js")||Z.includes("nextjs"))X.push("nextjs.org","vercel.com");if(Z.includes("playwright"))X.push("playwright.dev");if(Z.includes("supabase"))X.push("supabase.com","supabase.io");if(Z.includes("prisma"))X.push("prisma.io");if(Z.includes("tailwind"))X.push("tailwindcss.com");if(Z.includes("vite"))X.push("vitejs.dev","vite.dev");if(Z.includes("astro"))X.push("astro.build");if(Z.includes("svelte"))X.push("svelte.dev");if(Z.includes("solid"))X.push("solidjs.com");if(Z.includes("vue")||Z.includes("nuxt"))X.push("vuejs.org","nuxt.com");if(Z.includes("react")||Z.includes("react native"))X.push("react.dev","reactnative.dev");if(Z.includes("angular"))X.push("angular.io","angular.dev");if(Z.includes("node.js")||Z.includes("nodejs"))X.push("nodejs.org","nodejs.dev","npmjs.com");if(/\bgo\b/.test(Z)||Z.includes("golang"))X.push("go.dev","golang.org","pkg.go.dev");if(Z.includes("deno"))X.push("deno.land","deno.com");if(Z.includes("fresh"))X.push("fresh.deno.dev");if(Z.includes("typescript")||Z.includes("ts"))X.push("typescriptlang.org");if(Z.includes("python"))X.push("python.org","docs.python.org");if(Z.includes("rust"))X.push("rust-lang.org","docs.rs","crates.io");if(Z.includes("zig"))X.push("ziglang.org");if(Z.includes("docker"))X.push("docker.com","docs.docker.com","hub.docker.com");if(Z.includes("kubernetes")||Z.includes("k8s"))X.push("kubernetes.io","k8s.io");if(Z.includes("postgres")||Z.includes("postgresql"))X.push("postgresql.org","neon.tech","supabase.com");if(Z.includes("redis"))X.push("redis.io");if(Z.includes("sqlite"))X.push("sqlite.org");if(Z.includes("cloudflare"))X.push("developers.cloudflare.com","cloudflare.com");if(Z.includes("vercel"))X.push("vercel.com","nextjs.org");if(Z.includes("netlify"))X.push("netlify.com","docs.netlify.com");if(Z.includes("stripe"))X.push("stripe.com","docs.stripe.com");if(Z.includes("github"))X.push("github.com","docs.github.com");if(Z.includes("gitlab"))X.push("gitlab.com","docs.gitlab.com");if(Z.includes("aws"))X.push("aws.amazon.com","docs.aws.amazon.com");if(Z.includes("azure"))X.push("azure.microsoft.com","learn.microsoft.com");if(Z.includes("gcp")||Z.includes("google cloud"))X.push("cloud.google.com","developers.google.com");if(Z.includes("gemini")||Z.includes("google ai"))X.push("ai.google.dev","developers.google.com");for(let J of x2){let W=J.replace(/\.com$/,"");if(Z.includes(W))X.push(J)}return[...new Set(X)]}function b2($,Z){return $===Z||$.endsWith(`.${Z}`)}function q0($,Z=""){let X=new Map,J=Object.keys($||{}).filter((Q)=>!Q.startsWith("_")),W=h6(Z);for(let Q of J){let H=$[Q];if(!H?.sources)continue;for(let B=0;B<H.sources.length;B++){let N=H.sources[B],G=e(N.url);if(!G||G.length<10)continue;let O=M1(N.title||""),M=x6(G),D=z1(M,O,G),z=0;if(W.some((g)=>b2(M,g)))z+=10;if(D==="official-docs")z+=3;let F=G.toLowerCase();if(/\/docs\/|\/documentation\/|\.dev\/|\/api\/|\/reference\//.test(F))z+=2;let P=W.some((g)=>b2(M,g));if(D==="social"&&!P)z-=20;if(W.length>0){if(G$(M,y6))z-=3;else if(D==="community"&&!G$(M,["stackoverflow.com","stackexchange.com"]))z-=1}let w=X.get(G)||{id:"",canonicalUrl:G,displayUrl:N.url||G,domain:M,title:"",engines:[],engineCount:0,perEngine:{},sourceType:D,isOfficial:D==="official-docs",smartScore:0};if(w.title=D1(w.title,O),w.displayUrl=w.displayUrl||N.url||G,w.sourceType=w.sourceType||D,w.isOfficial=w.isOfficial||D==="official-docs",w.smartScore=Math.max(w.smartScore,z),!w.engines.includes(Q))w.engines.push(Q);w.perEngine[Q]={rank:B+1,title:D1(w.perEngine[Q]?.title||"",O)},X.set(G,w)}}let K=Array.from(X.values()).map((Q)=>({...Q,engineCount:Q.engines.length})),V=K.filter((Q)=>Q.sourceType!=="social"),j=K.filter((Q)=>Q.sourceType==="social");return V.sort((Q,H)=>{let B=l0(H)-l0(Q);if(B!==0)return B;return Q.domain.localeCompare(H.domain)}),j.sort((Q,H)=>{let B=l0(H)-l0(Q);if(B!==0)return B;return Q.domain.localeCompare(H.domain)}),[...V,...j].slice(0,12).map((Q,H)=>({...Q,id:`S${H+1}`,title:Q.title||Q.domain||Q.canonicalUrl}))}function t0($,Z){let X=new Map(Z.map((J)=>[J.id,J]));return $.map((J)=>{let W=X.get(J.id);if(!W)return J;let K=D1(J.title,W.title||"");return{...J,title:K||J.title,fetch:{attempted:!0,ok:!W.error&&W.contentChars>100,status:W.status||null,finalUrl:W.finalUrl||W.url||J.canonicalUrl,contentType:W.contentType||"",lastModified:W.lastModified||"",publishedTime:W.publishedTime||"",byline:W.byline||"",siteName:W.siteName||"",lang:W.lang||"",title:W.title||"",snippet:W.snippet||"",contentChars:W.contentChars||0,source:W.source||"unknown",duration:W.duration||0,error:W.error||""}}})}var E6,f6,b6,x2,y6;var E0=V0(()=>{E6=["fbclid","gclid","ref","ref_src","ref_url","source","utm_campaign","utm_content","utm_medium","utm_source","utm_term"],f6=["dev.to","hashnode.com","medium.com","reddit.com","stackoverflow.com","stackexchange.com","substack.com"],b6=["arstechnica.com","techcrunch.com","theverge.com","venturebeat.com","wired.com","zdnet.com"],x2=["facebook.com","instagram.com","linkedin.com","pinterest.com","tiktok.com","twitter.com","x.com"];y6=["reddit.com","news.ycombinator.com","lobste.rs"]});var U1={};s$(U1,{fetchTopSource:()=>r0,fetchSourceContent:()=>g2,fetchMultipleSources:()=>N$});async function p6($,Z,X=8000){let J=Date.now();try{let K=(await y(["evalraw",$,"Page.getFrameTree","{}"]).then((O)=>JSON.parse(O)).catch(()=>null))?.frameTree?.frame?.id||void 0,V=await y(["evalraw",$,"Network.loadNetworkResource",JSON.stringify({frameId:K,url:Z,options:{disableCache:!0,includeCredentials:!1}})],20000),Y=JSON.parse(V).resource;if(!Y?.success||!Y.httpStatusCode)return{url:Z,error:Y?.netErrorName||Y?.netError||"loadNetworkResource failed",source:"chrome",duration:Date.now()-J,needsFallback:!0};let Q="";if(Y.stream)try{let O=await y(["evalraw",$,"IO.read",JSON.stringify({handle:Y.stream})],1e4);Q=JSON.parse(O).data||"",await y(["evalraw",$,"IO.close",JSON.stringify({handle:Y.stream})]).catch(()=>{})}catch{}if(!Q||Q.length<100)return{url:Z,error:"Empty response body from Network.loadNetworkResource",source:"chrome",duration:Date.now()-J,needsFallback:!0};let H=Q1(Y.httpStatusCode,Q,Z,Z);if(H.blocked)return{url:Z,status:Y.httpStatusCode,error:`Blocked: ${H.reason}`,source:"chrome",duration:Date.now()-J,needsBrowser:!0};let B=await H1(Q,Z),N=B1(B);if(!N.ok)return{url:Z,status:Y.httpStatusCode,error:`Low quality: ${N.reason}`,source:"chrome",duration:Date.now()-J,needsBrowser:!0};let G=d0(B.markdown,X);return{url:Z,finalUrl:Z,status:Y.httpStatusCode,contentType:"text/markdown",lastModified:"",publishedTime:B.publishedTime||"",byline:B.byline||"",siteName:B.siteName||"",lang:B.lang||"",title:B.title||Z,snippet:B.excerpt,content:G,contentChars:G.length,source:"chrome",duration:Date.now()-J}}catch(W){return{url:Z,error:W.message,source:"chrome",duration:Date.now()-J,needsFallback:!0}}}function S2($){try{return new URL($).pathname.toLowerCase().endsWith(".pdf")}catch{return!1}}async function m6($,Z=8000){let X=y$($);if(X.blocked)return{url:$,finalUrl:$,status:403,error:`Blocked: ${X.reason}`,source:"pdf-http"};let J=new AbortController,W=setTimeout(()=>J.abort(),20000),K=Date.now();try{let V=await fetch($,{method:"GET",redirect:"follow",signal:J.signal,headers:_2({accept:"application/pdf,application/octet-stream;q=0.9,*/*;q=0.5"})});clearTimeout(W);let j=V.headers.get("content-type")||"",Y=V.url||$,Q=Number.parseInt(V.headers.get("content-length")||"0",10);if(V.status>=400)return{url:$,finalUrl:Y,status:V.status,error:`HTTP ${V.status}`,source:"pdf-http",duration:Date.now()-K};if(!j.toLowerCase().includes("application/pdf")&&!S2(Y))return null;if(Q>31457280)return{url:$,finalUrl:Y,status:V.status,error:`PDF too large: ${Q} bytes`,source:"pdf-http",duration:Date.now()-K};let H=Buffer.from(await V.arrayBuffer()),B=await f2(H,Y);if(!B||B.error)return{url:$,finalUrl:Y,status:V.status,error:B?.error||"PDF text extraction failed",source:"pdf-http",duration:Date.now()-K};let N=d0(B.content,Z);return{url:$,finalUrl:Y,status:V.status,contentType:"application/pdf",lastModified:V.headers.get("last-modified")||"",title:B.title,snippet:R(N,320),content:N,contentChars:N.length,pages:B.pages,source:"pdf-http",duration:Date.now()-K}}catch(V){return clearTimeout(W),{url:$,finalUrl:$,error:V.message||String(V),source:"pdf-http",duration:Date.now()-K}}}async function g2($,Z=8000){let X=Date.now();if(S2($)){let K=await m6($,Z);if(K?.content||K?.status===403)return K}if(B$($)){let K=B$($);if(K&&(K.type==="root"||K.type==="tree"||K.type==="blob"&&!K.path?.includes("."))){let V=await G1($);if(V.ok){let j=d0(V.content,Z);return{url:$,finalUrl:$,status:200,contentType:"text/markdown",lastModified:"",title:V.title,snippet:j.slice(0,320),content:j,contentChars:j.length,source:"github-api",...V.tree&&{tree:V.tree},duration:Date.now()-X}}process.stderr.write(`[greedysearch] GitHub API fetch failed, trying HTTP: ${V.error}
|
|
349
|
+
`)}}if(I2($)?.type==="post"){process.stderr.write(`[greedysearch] Using Reddit JSON API for: ${$.slice(0,60)}...
|
|
350
|
+
`);let K=await v2($,Z);if(K.ok){let V=d0(K.markdown,Z);return{url:$,finalUrl:K.finalUrl,status:K.status,contentType:"text/markdown",lastModified:K.lastModified||"",publishedTime:K.publishedTime||"",byline:K.byline||"",siteName:K.siteName||"",lang:K.lang||"",title:K.title,snippet:K.excerpt,content:V,contentChars:V.length,source:"reddit-api",duration:Date.now()-X}}process.stderr.write(`[greedysearch] Reddit API fetch failed, falling back to HTTP: ${K.error}
|
|
351
|
+
`)}let W=await k2($,{timeoutMs:1e4});if(W.ok){let K=d0(W.markdown,Z);return{url:$,finalUrl:W.finalUrl,status:W.status,contentType:"text/markdown",lastModified:W.lastModified||"",publishedTime:W.publishedTime||"",byline:W.byline||"",siteName:W.siteName||"",lang:W.lang||"",title:W.title,snippet:W.excerpt,content:K,contentChars:K.length,source:"http",duration:Date.now()-X}}if(W.needsBrowser)try{let K=await T0();try{let V=await p6(K,$,Z);if(V.content&&V.content.length>100)return V}finally{await I0(K)}}catch{}return process.stderr.write(`[greedysearch] HTTP failed for ${$.slice(0,60)}, trying browser...
|
|
352
|
+
`),await d6($,Z)}async function y2($,Z=4000,X=200){let J=Date.now()+Z;while(Date.now()<J){try{if((await y(["eval",$,'document.readyState === "complete" && !!document.body && document.body.innerText.length > 500'])).trim()==="true")return}catch{}await new Promise((W)=>setTimeout(W,X))}}async function d6($,Z=8000){let X=Date.now(),J;try{J=await T0()}catch(W){return{url:$,title:"",content:null,snippet:"",contentChars:0,error:`openNewTab failed: ${W.message}`,source:"browser",duration:Date.now()-X}}try{await y(["nav",J,$],30000),await y2(J);let W=await y(["eval",J,String.raw`
|
|
277
353
|
(function(){
|
|
278
354
|
var el = document.querySelector('article, [role="main"], main, .post-content, .article-body, #content, .content');
|
|
279
355
|
var text = (el || document.body).innerText;
|
|
@@ -283,19 +359,19 @@ ${K}`,pages:W.total}}catch(X){return{error:X.message||String(X)}}}function b($="
|
|
|
283
359
|
url: location.href
|
|
284
360
|
});
|
|
285
361
|
})()
|
|
286
|
-
`]),K=JSON.parse(W),V=
|
|
287
|
-
`);let V=Array(W.length),
|
|
288
|
-
`);let
|
|
289
|
-
`);else if(
|
|
290
|
-
`);
|
|
291
|
-
`)}}await Promise.all(Array.from({length:K},()=>Q()));let
|
|
292
|
-
`),V}async function
|
|
362
|
+
`]),K=JSON.parse(W),V=d0(K.content,Z);return{url:$,finalUrl:K.url||$,status:200,contentType:"text/plain",lastModified:"",title:K.title,snippet:R(V,320),content:V,contentChars:V.length,source:"browser",duration:Date.now()-X}}catch(W){return{url:$,title:"",content:null,snippet:"",contentChars:0,error:W.message,source:"browser",duration:Date.now()-X}}finally{await I0(J)}}async function N$($,Z=5,X=8000,J=J1){let W=$.slice(0,Z);if(W.length===0)return[];let K=Math.min(W.length,Math.max(1,Number.parseInt(String(J),10)||J1));process.stderr.write(`[greedysearch] Fetching content from ${W.length} sources via HTTP (concurrency ${K})...
|
|
363
|
+
`);let V=Array(W.length),j=0,Y=0;async function Q(){while(!0){let G=j++;if(G>=W.length)return;let O=W[G],M=O.canonicalUrl||O.url;process.stderr.write(`[greedysearch] [${G+1}/${W.length}] Fetching: ${M.slice(0,60)}...
|
|
364
|
+
`);let D=await g2(M,X).catch((z)=>({url:M,title:"",content:null,snippet:"",contentChars:0,error:z.message,source:"error",duration:0}));if(V[G]={id:O.id,...D},D.content&&D.content.length>100)process.stderr.write(`[greedysearch] ✓ ${D.source}: ${D.content.length} chars
|
|
365
|
+
`);else if(D.error)process.stderr.write(`[greedysearch] ✗ ${D.error.slice(0,80)}
|
|
366
|
+
`);Y+=1,process.stderr.write(`PROGRESS:fetch:${Y}/${W.length}
|
|
367
|
+
`)}}await Promise.all(Array.from({length:K},()=>Q()));let H=V.filter((G)=>G.content&&G.content.length>100),B=V.filter((G)=>G.source==="http").length,N=V.filter((G)=>G.source==="browser").length;return process.stderr.write(`[greedysearch] Fetched ${H.length}/${V.length} sources (HTTP: ${B}, Browser: ${N})
|
|
368
|
+
`),V}async function r0($){let Z=await T0();try{await y(["nav",Z,$],30000),await y2(Z);let X=await y(["eval",Z,String.raw`
|
|
293
369
|
(function(){
|
|
294
370
|
var el = document.querySelector('article, [role="main"], main, .post-content, .article-body, #content, .content');
|
|
295
371
|
var text = (el || document.body).innerText;
|
|
296
372
|
return text.replace(/\s+/g, ' ').trim();
|
|
297
373
|
})()
|
|
298
|
-
`]);return{url:$,content:X}}catch(X){return{url:$,content:null,error:X.message}}finally{await
|
|
374
|
+
`]);return{url:$,content:X}}catch(X){return{url:$,content:null,error:X.message}}finally{await I0(Z)}}var O$=V0(()=>{L2();N1();E2();Y1();D0();E0()});var m2={};s$(m2,{writeSourcesToFiles:()=>e0});import{mkdirSync as n6,writeFileSync as i6}from"node:fs";import{join as p2}from"node:path";function e0($,Z=a6){return n6(Z,{recursive:!0}),$.map((X)=>{if(!X.content||X.content.length<10)return X;let J=String(X.id||"unknown").replace(/[^a-zA-Z0-9_-]/g,""),W=(X.canonicalUrl||X.url||"").replace(/^https?:\/\//,"").replace(/[^a-zA-Z0-9]/g,"-").slice(0,40),K=`${J}-${W}.md`,V=p2(Z,K),j=`---
|
|
299
375
|
url: ${X.finalUrl||X.url}
|
|
300
376
|
title: ${X.title||""}
|
|
301
377
|
source: ${X.source||"unknown"}
|
|
@@ -303,102 +379,178 @@ status: ${X.status||""}
|
|
|
303
379
|
chars: ${X.contentChars||X.content.length}
|
|
304
380
|
---
|
|
305
381
|
|
|
306
|
-
`;
|
|
307
|
-
`),
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
382
|
+
`;i6(V,j+X.content,"utf8");let{content:Y,...Q}=X;return{...Q,contentPath:V,contentChars:X.contentChars||Y.length}})}var a6;var h$=V0(()=>{a6=p2(process.cwd(),".dm","greedysearch-sources")});Y1();D0();import{appendFileSync as z9,existsSync as U9,readFileSync as F9}from"node:fs";import{homedir as w9}from"node:os";import{join as n$}from"node:path";x0();D0();import{spawn as G6}from"node:child_process";import{existsSync as D2}from"node:fs";import{dirname as Q6,join as S$}from"node:path";import{fileURLToPath as H6}from"node:url";function o0($){return H6(new URL(".",$)).replace(/^\/([A-Z]:)/,"$1")}function B6($,Z=D2){let X=new Set;for(let J of $.filter(Boolean)){if(X.has(J))continue;if(X.add(J),Z(J))return J}return $.filter(Boolean).at(-1)}function s0($,{moduleDir:Z,entrypoint:X=process.argv[1],env:J=process.env,exists:W=D2}={}){let K=X?Q6(X):null,V=J.GREEDY_SEARCH_EXTENSION_DIR?.trim()||null;return B6([Z?S$(Z,"..","..","extractors",$):null,Z?S$(Z,"..","extractors",$):null,V?S$(V,"extractors",$):null,K?S$(K,"..","extractors",$):null],W)}var N6=o0(import.meta.url);function v0($,Z,X=null,J=!1,W=null,K=null){if(W===null)W=$.includes("logically")?120000:$.includes("chatgpt")?80000:$.includes("gemini")?70000:60000;let V=[...X?["--tab",X]:[],...J?["--short"]:[],...K?["--locale",K]:[]];return new Promise((j,Y)=>{let Q=s0($,{moduleDir:N6}),H=G6(H0(),[Q,"--stdin",...V],{stdio:["pipe","pipe","pipe"],env:{...process.env,CDP_PROFILE_DIR:u}});H.stdin.write(Z),H.stdin.end();let B="",N="";H.stdout.on("data",(O)=>B+=O),H.stderr.on("data",(O)=>{if(N+=O,process.env.GREEDY_SEARCH_CHILD_STDERR!=="0")process.stderr.write(O)});let G=setTimeout(()=>{H.kill();let O=(z,F=20)=>String(z??"").split(/\r?\n/).filter(Boolean).slice(-F).join(`
|
|
383
|
+
`),M=null;try{let z=JSON.parse(B.trim());if(z._envelope)M=z._envelope}catch{}let D=Error(`${$} timed out after ${W/1000}s`+(M?.lastStage?` (last stage: ${M.lastStage})`:""));D.engineScript=$,D.lastStage=M?.lastStage||null,D.partialErr=O(N),D.partialOut=O(B),Y(D)},W);H.on("close",(O)=>{if(clearTimeout(G),O===0)try{j(JSON.parse(B.trim()))}catch{Y(Error(`bad JSON from ${$}: ${B.slice(0,100)}`))}else{let M=null;try{let F=JSON.parse(B.trim());if(F._envelope)M=F._envelope}catch{}let D=N.trim()||`extractor exit ${O}`,z=Error(D);if(M)z.envelope=M;Y(z)}})})}O$();r$();var l6=Number.parseInt(process.env.GREEDY_SEARCH_CHALLENGE_WAIT_MS||"300000",10),u6=3000,h2={chatgpt:{name:"chatgpt",isCleared:async($)=>{let Z=await S0(["eval",$,`(() => {
|
|
384
|
+
const title = document.title;
|
|
385
|
+
const onChatGPT = location.hostname === "chatgpt.com";
|
|
386
|
+
const hasProseMirror = !!document.querySelector("div.ProseMirror");
|
|
387
|
+
const hasTurnstileInput =
|
|
388
|
+
!!document.querySelector("input[name=\\"cf-turnstile-response\\"]") ||
|
|
389
|
+
!!document.querySelector("iframe[id^=\\"cf-chl-widget-\\"]");
|
|
390
|
+
// Body innerText is empty while on the Turnstile page.
|
|
391
|
+
const bodyText = (document.body && document.body.innerText) || "";
|
|
392
|
+
return JSON.stringify({
|
|
393
|
+
title,
|
|
394
|
+
url: location.href,
|
|
395
|
+
hasProseMirror,
|
|
396
|
+
hasTurnstileInput,
|
|
397
|
+
bodyLen: bodyText.length,
|
|
398
|
+
onChatGPT,
|
|
399
|
+
});
|
|
400
|
+
})()`]).catch(()=>null);if(!Z)return!1;let X;try{X=JSON.parse(Z)}catch{return!1}if(!X.onChatGPT)return!1;if(X.title&&/περιμένετε|please wait|just a moment|verifying|checking/i.test(X.title))return!1;if(X.hasTurnstileInput)return!1;return X.hasProseMirror||X.bodyLen>50}},bing:{name:"bing",isCleared:async($)=>{let Z=await S0(["eval",$,`(() => {
|
|
401
|
+
const url = location.href;
|
|
402
|
+
const title = document.title;
|
|
403
|
+
const onCopilot = /copilot\\.microsoft\\.com/.test(location.hostname);
|
|
404
|
+
const onChallenge =
|
|
405
|
+
/challenge|turnstile|cdn-cgi\\/challenge/i.test(url) ||
|
|
406
|
+
/verify|human|robot/i.test(title);
|
|
407
|
+
const hasTextarea =
|
|
408
|
+
!!document.querySelector("textarea") ||
|
|
409
|
+
!!document.querySelector("div[contenteditable=\\"true\\"]");
|
|
410
|
+
const hasTurnstileInput =
|
|
411
|
+
!!document.querySelector("iframe[id^=\\"cf-chl-widget-\\"]") ||
|
|
412
|
+
!!document.querySelector("input[name=\\"cf-turnstile-response\\"]");
|
|
413
|
+
const bodyText = (document.body && document.body.innerText) || "";
|
|
414
|
+
return JSON.stringify({
|
|
415
|
+
url,
|
|
416
|
+
title,
|
|
417
|
+
onCopilot,
|
|
418
|
+
onChallenge,
|
|
419
|
+
hasTextarea,
|
|
420
|
+
hasTurnstileInput,
|
|
421
|
+
bodyLen: bodyText.length,
|
|
422
|
+
});
|
|
423
|
+
})()`]).catch(()=>null);if(!Z)return!1;let X;try{X=JSON.parse(Z)}catch{return!1}if(!X.onCopilot)return!1;if(X.onChallenge)return!1;if(X.hasTurnstileInput)return!1;return X.hasTextarea||X.bodyLen>50}}};async function c6($){let Z=await S0(["eval",$,`(() => {
|
|
424
|
+
const cookies = document.cookie || "";
|
|
425
|
+
return JSON.stringify({
|
|
426
|
+
hasCfClearance: /(?:^|;\\s*)cf_clearance=/.test(cookies),
|
|
427
|
+
hasCfBm: /(?:^|;\\s*)__cf_bm=/.test(cookies),
|
|
428
|
+
cookiesLength: cookies.length,
|
|
429
|
+
});
|
|
430
|
+
})()`]).catch(()=>null);if(!Z)return!1;try{let X=JSON.parse(Z);return X.hasCfClearance||X.hasCfBm}catch{return!1}}async function F1({tab:$,engine:Z,timeoutMs:X=l6,intervalMs:J=u6,signal:W,log:K=()=>{}}){let V=h2[Z],j=Date.now(),Y=null;while(Date.now()-j<X){if(W?.aborted)return{cleared:!1,reason:"aborted"};let Q=Math.floor((Date.now()-j)/1000),H=!1;if(V)H=await V.isCleared($).catch(()=>!1);else H=await c6($).catch(()=>!1);if(H)return K(`[greedysearch] ✅ ${Z} challenge cleared after ${Q}s — auto-resuming extraction.`),{cleared:!0,signal:V?"dom-marker":"cookie"};if(Q>0&&Q%30===0&&Y!==Q)Y=Q,K(`[greedysearch] ⏳ Waiting for ${Z} challenge to clear (${Q}s/${Math.floor(X/1000)}s)...`);await new Promise((B)=>setTimeout(B,J))}return{cleared:!1,reason:`Challenge not cleared within ${Math.floor(X/1000)}s`}}var p4=Object.keys(h2);h$();import{mkdirSync as o6,readdirSync as s6,rmSync as t6,statSync as r6,writeFileSync as w1}from"node:fs";import{join as p$}from"node:path";var e6=import.meta.dirname||new URL(".",import.meta.url).pathname.replace(/^\/([A-Z]:)/,"$1");function $7($){return $.toLowerCase().replaceAll(/[^a-z0-9]+/g,"-").replaceAll(/^-|-$/g,"").slice(0,60)}var Z7=604800000,X7=10;function J7($){try{let Z=s6($).filter((J)=>J.endsWith(".json")||J.endsWith(".md")).map((J)=>({f:J,mtime:r6(p$($,J)).mtimeMs})).sort((J,W)=>W.mtime-J.mtime),X=Date.now()-Z7;for(let J=X7;J<Z.length;J++)if(Z[J].mtime<X)t6(p$($,Z[J].f),{force:!0})}catch{}}function W7(){let $=p$(e6,"..","..","results");return o6($,{recursive:!0}),J7($),$}function u0($,Z,{inline:X=!1,synthesize:J=!1,query:W=""}={}){let K=`${JSON.stringify($,null,2)}
|
|
431
|
+
`;if(Z){w1(Z,K,"utf8"),process.stderr.write(`Results written to ${Z}
|
|
432
|
+
`);return}if(X){process.stdout.write(K);return}let V=new Date().toISOString().replaceAll("T","_").replaceAll(/[:.]/g,"-").slice(0,19),j=$7(W),Y=p$(W7(),`${V}_${j}`);if(w1(`${Y}.json`,K,"utf8"),J&&$._synthesis?.answer)w1(`${Y}-synthesis.md`,$._synthesis.answer,"utf8"),process.stdout.write(`${Y}-synthesis.md
|
|
433
|
+
`);else process.stdout.write(`${Y}.json
|
|
434
|
+
`)}var K7=["perplexity","bing","chatgpt","semantic-scholar","logically"],d2=new Set(["rate-limit"]),V7=/timed out|timeout|verification|captcha|cloudflare|turnstile|input not found|ask-input|copy button hidden|sign.in|login required/i,j7=/needs-human|verification required|please solve|captcha|cloudflare|turnstile|could not be completed automatically|manual intervention|sign.in|login required/i;function l2($){return V7.test(String($||""))}function P1($){return j7.test(String($||""))}function u2($){return K7.filter((Z)=>{let X=$?.[Z];if(!X)return!1;let J=X._envelope?.blockedBy;if(J){if(d2.has(J))return!1;return!0}if(X._envelope?.verificationResult==="needs-human")return!0;let W=X.error;return W&&l2(W)})}function c2($){if(!$)return!1;let Z=$.envelope;if(Z?.blockedBy){if(d2.has(Z.blockedBy))return!1;return!0}if(Z?.verificationResult==="needs-human")return!0;return l2($.message)}E0();D0();E0();function Y7($){let Z="",X=!1,J=!1;for(let W of String($)){if(J){Z+=W,J=!1;continue}if(W==="\\"){Z+=W,J=!0;continue}if(W==='"'){X=!X,Z+=W;continue}if(X&&W===`
|
|
435
|
+
`)Z+="\\n";else if(X&&W==="\r")Z+="\\r";else if(X&&W==="\t")Z+="\\t";else Z+=W}return Z}function z0($){if(!$)return null;let Z=String($).trim(),X=Z.indexOf("BEGIN_JSON"),J=Z.indexOf("END_JSON");if(X!==-1&&J!==-1&&X<J)Z=Z.slice(X+10,J).trim();else{let j=Z.indexOf("{");if(j>0)Z=Z.slice(j)}let W=[Z,Z.replace(/^```json\s*/i,"").replace(/^```\s*/i,"").replace(/```$/i,"").trim()],K=Z.indexOf("{"),V=Z.lastIndexOf("}");if(K!==-1&&V!==-1&&K<V)W.push(Z.slice(K,V+1));for(let j of[...W]){let Y=Y7(j);if(Y!==j)W.push(Y)}for(let j of W)try{return JSON.parse(j)}catch{}return null}function n2($,Z,X=""){let J=new Set(Z.map((Y)=>Y.id)),W=["high","medium","low","mixed","conflicting"].includes($?.agreement?.level)?$.agreement.level:"mixed",K=Array.isArray($?.claims)?$.claims.map((Y)=>({claim:R(Y?.claim||"",260),support:["strong","moderate","weak","conflicting"].includes(Y?.support)?Y.support:"moderate",sourceIds:Array.isArray(Y?.sourceIds)?Y.sourceIds.filter((Q)=>J.has(Q)):[]})).filter((Y)=>Y.claim):[],V=Array.isArray($?.recommendedSources)?$.recommendedSources.filter((Y)=>J.has(Y)).slice(0,6):[],j="";if(X){let Y=X.indexOf("{"),Q=X.lastIndexOf("}");if(Y!==-1&&Q!==-1&&Y<Q)j=X.slice(Y,Q+1);else j=X}return{answer:R($?.answer||j||X,4000),agreement:{level:W,summary:R($?.agreement?.summary||"",280)},differences:Array.isArray($?.differences)?$.differences.map((Y)=>R(Y,220)).filter(Boolean).slice(0,5):[],caveats:Array.isArray($?.caveats)?$.caveats.map((Y)=>R(Y,220)).filter(Boolean).slice(0,5):[],claims:K,recommendedSources:V}}function i2($,Z,X,{grounded:J=!1}={}){let W={};for(let j of["perplexity","bing","google"]){let Y=Z[j];if(!Y)continue;if(Y.error){W[j]={status:"error",error:String(Y.error)};continue}W[j]={status:"ok",answer:R(Y.answer||"",J?4500:2200),sourceIds:X.filter((Q)=>Q.engines.includes(j)).sort((Q,H)=>(Q.perEngine[j]?.rank||99)-(H.perEngine[j]?.rank||99)).map((Q)=>Q.id).slice(0,6)}}let K=J?700:300,V=X.slice(0,J?10:8).map((j)=>({id:j.id,title:j.title,domain:j.domain,canonicalUrl:j.canonicalUrl,sourceType:j.sourceType,isOfficial:j.isOfficial,engines:j.engines,engineCount:j.engineCount,fetch:j.fetch?.attempted?{ok:j.fetch.ok,publishedTime:j.fetch.publishedTime||"",byline:j.fetch.byline||"",snippet:R(j.fetch.snippet||"",K)}:void 0}));return["You are a research synthesizer. Combine these search engine results into a single authoritative answer.","",`Query: ${$}`,"",`Engine summaries:
|
|
313
436
|
${JSON.stringify(W,null,2)}`,"",`Source registry:
|
|
314
437
|
${JSON.stringify(V,null,2)}`,"","Instructions:","- Write a clear, direct answer in markdown (use headers/bullets where they help readability)","- Cite sources inline as [S1], [S2] etc. when making specific claims","- Prefer sources with content (fetch.ok=true and non-empty snippet) for citations","- Note where the engines agree or meaningfully disagree","- List any important caveats or limitations","- recommendedSources: the 2-4 source IDs most worth reading for this query","","Respond ONLY with a JSON object wrapped in BEGIN_JSON / END_JSON markers:","","BEGIN_JSON",JSON.stringify({answer:"<your markdown answer here>",agreement:{level:"high|medium|mixed|conflicting",summary:"<one sentence>"},differences:["<notable difference between engines, if any>"],caveats:["<important caveat or limitation>"],recommendedSources:["S1","S2"]},null,2),"END_JSON"].join(`
|
|
315
|
-
`)}function
|
|
316
|
-
|
|
317
|
-
`)
|
|
318
|
-
`),{
|
|
438
|
+
`)}function a2($){let Z=Array.isArray($._sources)?$._sources:[],X=Z.length>0?Z[0]?.engineCount||0:0,J=Z.filter((Q)=>Q.isOfficial).length,W=Z.filter((Q)=>Q.isOfficial||Q.sourceType==="maintainer-blog").length,K=Z.filter((Q)=>Q.fetch?.attempted).length,V=Z.filter((Q)=>Q.fetch?.ok).length,j=Z.reduce((Q,H)=>{return Q[H.sourceType]=(Q[H.sourceType]||0)+1,Q},{}),Y=$._synthesis?.agreement?.level;return{sourcesCount:Z.length,topSourceConsensus:X,agreementLevel:Y||(X>=3?"high":X>=2?"medium":"low"),enginesResponded:r.filter((Q)=>$[Q]?.answer&&!$[Q]?.error),enginesFailed:r.filter((Q)=>$[Q]?.error),officialSourceCount:J,firstPartySourceCount:W,fetchedSourceSuccessRate:K>0?Number((V/K).toFixed(2)):0,sourceTypeBreakdown:j}}x0();D0();import{spawn as Q7}from"node:child_process";E0();var H7=o0(import.meta.url),B7={gemini:"gemini.mjs",chatgpt:"chatgpt.mjs"},G7={gemini:"https://gemini.google.com/app",chatgpt:"https://chatgpt.com/"};function M$($="gemini"){let Z=String($||"gemini").toLowerCase();if(Z==="gem")return"gemini";if(Z==="gpt")return"chatgpt";return Z}function o2($="gemini"){return G7[M$($)]||"about:blank"}async function s2($,Z,{tabPrefix:X=null,timeoutMs:J=180000,visible:W=null}={}){let K=M$($),V=B7[K];if(!V||!J$.includes(K))throw Error(`Unsupported synthesizer "${$}". Supported: ${J$.join(", ")}`);return new Promise((j,Y)=>{let Q=s0(V,{moduleDir:H7}),H=X?["--tab",String(X)]:[],B={...process.env,CDP_PROFILE_DIR:u};if(W!==!0)delete B.GREEDY_SEARCH_VISIBLE,delete B.GREEDY_SEARCH_ALWAYS_VISIBLE;else B.GREEDY_SEARCH_VISIBLE="1",B.GREEDY_SEARCH_ALWAYS_VISIBLE="1";let N=Q7(H0(),[Q,"--stdin",...H],{stdio:["pipe","pipe","pipe"],env:B});N.stdin.write(Z),N.stdin.end();let G="",O="";N.stdout.on("data",(D)=>G+=D),N.stderr.on("data",(D)=>O+=D);let M=setTimeout(()=>{N.kill(),Y(Error(`${K} prompt timed out after ${J/1000}s`))},J);N.on("close",(D)=>{if(clearTimeout(M),D!==0){Y(Error(O.trim()||`${K} extractor failed`));return}try{j(JSON.parse(G.trim()))}catch{Y(Error(`bad JSON from ${K}: ${G.slice(0,100)}`))}})})}async function B0($,Z={}){return s2("gemini",$,Z)}async function t2($,Z,{grounded:X=!1,tabPrefix:J=null,visible:W=null,synthesizer:K="gemini"}={}){let V=M$(K),j=Array.isArray(Z._sources)?Z._sources:q0(Z),Y=i2($,Z,j,{grounded:X}),Q=await s2(V,Y,{tabPrefix:J,timeoutMs:180000,visible:W}),H=z0(Q.answer||""),N=H&&["answer","agreement","claims","differences","caveats"].some((O)=>(O in H));if(H&&["perplexity","bing","google","chatgpt","gemini"].some((O)=>(O in H))&&!N)H=null;return{...n2(H,j,Q.answer||""),rawAnswer:Q.answer||"",synthesizedBy:V,synthesizerSources:Q.sources||[],geminiSources:V==="gemini"?Q.sources||[]:[]}}var N7=/^(can you |could you |please |would you mind |i need to (know|understand) |i want to (know|understand) |i('m| am) (looking for|wondering about|curious about) |i need (information|info) (about|on) |tell me )?(about |explain |describe |give me |help me understand |search for |look up |find |research )?(about |regarding |on |for )?(it|this|the following)?\s*/i,O7=/\b(latest|newest|current|recent|up-to-date|up to date)\b/i,M7=/\b\d+\.\d+|\bv\d+\b|\b20(2[0-9]|[3-9]\d)\b/i;function D7($){let Z=$.trim().replace(N7,"").trim();return Z.length>4?Z:$.trim()}function z7($,Z=new Date().getFullYear()){if(!O7.test($))return $;if(M7.test($))return $;return`${$.trimEnd()} ${Z}`}function m$($){if(!$?.trim())return $;let Z=D7($);return Z=z7(Z),Z||$}x0();E0();import{spawn as b7}from"node:child_process";import{mkdirSync as I1,writeFileSync as j0}from"node:fs";import{join as m}from"node:path";import{fileURLToPath as x7}from"node:url";D0();E0();var U7=30000;function r2($,Z,X,J){let W=Number.parseInt(String($??""),10);if(!Number.isFinite(W))return J;return Math.min(X,Math.max(Z,W))}async function e2($){let Z=["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: "+$].join(`
|
|
439
|
+
`);try{let X=await B0(Z,{timeoutMs:U7}),J=z0(X?.answer||"")||{},W=["simple","moderate","complex"].includes(J.complexity)?J.complexity:"moderate";return{complexity:W,reasoning:R(J.reasoning||"",200),suggestedBreadth:r2(J.suggestedBreadth,1,5,W==="simple"?1:3),suggestedIterations:r2(J.suggestedIterations,1,3,W==="simple"?1:2),needsAcademicSources:J.needsAcademicSources===!0}}catch(X){return process.stderr.write(`[greedysearch] Complexity classification failed, defaulting to moderate: ${X.message}
|
|
440
|
+
`),{complexity:"moderate",reasoning:"classification failed",suggestedBreadth:3,suggestedIterations:2,needsAcademicSources:!1}}}D0();E0();h$();O$();function F7($){if($<1000)return"0s";let Z=Math.round($/1000);if(Z<60)return`${Z}s`;let X=Math.floor(Z/60),J=Z%60;return`${X}m ${J}s`}function w7($,Z=20){let X=Math.round($*Z),J=Z-X;return"["+"█".repeat(X)+"░".repeat(J)+"]"}function d$({totalActions:$=0,totalRounds:Z=0,totalFetches:X=0,silent:J=!1}={}){let W=Date.now(),K=0,V=0,j=0,Y=[],Q=null,H=null,B=0,N=500;function G(z){if(Y.push(z),Y.length>5)Y.shift()}function O(){if(Y.length===0)return null;return Y.reduce((z,F)=>z+F,0)/Y.length}function M(z){let F=Date.now()-W,P=$+X+Z,w=K+j+V,g=P>0?Math.min(1,w/P):0,d=w7(g),f=O(),x=Math.max(0,P-w),i=f?f*x:null,G0=i?F7(i):"—",o=H?` ${H}`:"";return`${d} ${w}/${P} (${z}${o}, ETA ${G0})`}function D(z){if(J)return;let F=Date.now();if(F-B<N&&z!=="done")return;B=F,process.stderr.write(`[greedysearch] ${M(z)}
|
|
441
|
+
`)}return{startRound(z){V=z-1},endRound(){V++,D("round")},startAction(z,F){Q=Date.now(),H=`${z}:${(F||"").slice(0,40)}`,D(z)},endAction(){if(Q)G(Date.now()-Q),Q=null;K++,D("action")},startFetch(z){Q=Date.now(),H=`fetch:${(z||"").slice(0,40)}`,D("fetch")},endFetch(z=!0){if(Q)G(Date.now()-Q),Q=null;j++,D(z?"fetch":"fetch-failed")},print(){D("progress")},finish(){D("done")},getElapsedMs(){return Date.now()-W}}}x0();import{spawn as P7}from"node:child_process";import{join as _7}from"node:path";import{fileURLToPath as k7}from"node:url";var L7=k7(new URL(".",import.meta.url)).replace(/^\/([A-Z]:)/,"$1"),A7=_7(L7,"..","..","bin","search.mjs");function $8($,Z=1/0){let X=new Set,J=[];for(let W of $||[]){let K=R(String(W||""),1000);if(!K||X.has(K))continue;if(X.add(K),J.push(K),J.length>=Z)break}return J}function T7($){let Z=String($||"").trim();if(!Z)return[];return[`${Z} — definition and overview`,`${Z} — how it works, mechanism, or key details`,`${Z} — current usage, comparison, or best practices`]}function C7($,Z){let X=new Map;for(let J of $||[]){let W=J?.canonicalUrl||J?.finalUrl||J?.url;if(W)X.set(W,J)}for(let J of Z||[]){let W=J?.canonicalUrl||J?.finalUrl||J?.url;if(!W)continue;if(X.has(W)){let K={...X.get(W),angles:[...X.get(W).angles||[X.get(W).query||""],J.query||""]};X.set(W,K)}else X.set(W,J)}return Array.from(X.values())}var R7=r.join("|"),I7=new RegExp(`^\\[(${R7})\\]`);function v7($){return/^PROGRESS:/.test($)||/^\[greedysearch\]/.test($)||I7.test($)||/^GreedySearch Chrome/.test($)||/^Launching GreedySearch Chrome/.test($)||/^Headless mode/.test($)||/^Ready\.?$/.test($)}async function q7($,{locale:Z=null,short:X=!0}={}){let J=[A7,"all","--inline","--stdin","--fast"];if(!X)J.push("--full");if(Z)J.push("--locale",Z);return new Promise((W,K)=>{let V=P7(H0(),J,{stdio:["pipe","pipe","pipe"],env:{...process.env,GREEDY_SEARCH_RESEARCH_CHILD:"1"}});V.stdin.write($),V.stdin.end();let j="",Y="",Q="";V.stdout.on("data",(B)=>j+=B),V.stderr.on("data",(B)=>{Y+=B,Q+=B.toString();let N=Q.split(`
|
|
442
|
+
`);Q=N.pop()||"";for(let G of N)if(v7(G))process.stderr.write(`${G}
|
|
443
|
+
`)});let H=setTimeout(()=>{V.kill(),K(Error(`research child search timed out for: ${$}`))},140000);V.on("close",(B)=>{if(clearTimeout(H),B!==0){K(Error(Y.trim()||`search child exited with code ${B}`));return}try{W(JSON.parse(j.trim()))}catch{K(Error(`Invalid JSON from research child: ${j.slice(0,200)}`))}})})}function E7($,Z){let X=new Map;for(let J of Z||[]){let W=e(J?.canonicalUrl||J?.finalUrl||J?.url);if(W&&J?.id)X.set(W,J.id)}return($||[]).map((J,W)=>{let K=e(J?.finalUrl||J?.canonicalUrl||J?.url);return{...J,id:J?.id||X.get(K)||`F${W+1}`}})}function f7($){let Z=$.length,X=$.filter((J)=>J.status==="closed").length;return{total:Z,closed:X,open:Math.max(0,Z-X)}}async function Z8({query:$,locale:Z=null,maxSources:X=5,qualityThreshold:J=8.5,writeBundle:W=process.env.GREEDY_RESEARCH_BUNDLE!=="0",researchOutDir:K=null}={}){let V=new Date().toISOString(),j=Date.now(),Y=T1($),Q=new Set;process.stderr.write(`[greedysearch] Simple research mode: single-pass for "${R($,80)}"
|
|
444
|
+
`);let N=d$({totalActions:6,totalRounds:1,totalFetches:1,silent:process.env.GREEDY_RESEARCH_QUIET==="1"});N.startRound(1);let G=[],O=[],M=T7($),D=[];N.startAction("search",`${M.length} angles in parallel`);let z=await Promise.allSettled(M.map((T)=>q7(T,{locale:Z,short:!0})));for(let T=0;T<M.length;T++){let $0=M[T],c=z[T];if(N.endAction(),c.status==="fulfilled"){let s=c.value;D.push({angle:$0,result:s});let q=q0(s,$0);G=C7(G,q)}else process.stderr.write(`[greedysearch] Simple search angle "${$0}" failed: ${c.reason.message}
|
|
445
|
+
`)}if(process.stderr.write(`PROGRESS:research:simple:fetching
|
|
446
|
+
`),G.length>0)try{N.startFetch(`top ${Math.min(X,G.length)} sources`),O=await N$(G,Math.min(X,G.length),8000,Math.min(3,X)),N.endFetch(!0),G=t0(G,O)}catch(T){N.endFetch(!1),process.stderr.write(`[greedysearch] Source fetching failed: ${T.message}
|
|
447
|
+
`)}O=E7(O,G),process.stderr.write(`PROGRESS:research:simple:evidence
|
|
448
|
+
`);let F=[];try{let T=await X8({query:$,questions:Y,fetchedSources:O,extractedSourceKeys:Q});F=T.evidence||[];for(let $0 of T.evidence){let c=Array.isArray($0.answers)?$0.answers:[];for(let q of c){let F0=q?.id||q?.question;if(F0){let b=Y.find((W0)=>W0.id===F0);if(b){if(b.status="closed",b.closedRound=1,q.evidence)b.evidence=$8([...b.evidence||[],q.evidence],4)}}}let s=Array.isArray($0.newQuestions)?$0.newQuestions:[];for(let q of s){let F0=R(String(q),320);if(F0&&!Y.some((b)=>b.question===F0))Y.push({id:`Q${Y.length+1}`,question:F0,status:"open",reason:"Discovered gap/follow-up",createdRound:1,evidence:[],sourceIds:[]})}}}catch(T){process.stderr.write(`[greedysearch] Evidence extraction failed: ${T.message}
|
|
449
|
+
`)}process.stderr.write(`PROGRESS:research:simple:synthesizing
|
|
450
|
+
`);let P={answer:"",agreement:{level:"mixed",summary:"Single-pass synthesis."},differences:[],caveats:[],claims:[],recommendedSources:G.slice(0,4).map((T)=>T.id),synthesized:!1};if(F.length>0)try{N.startAction("synth-evidence","from evidence");let T=await B0(k1($,G,Y,F),{timeoutMs:120000});N.endAction(),P={...P,...z0(T?.answer||"")||{}},P.synthesized=Array.isArray(P.claims)&&P.claims.length>0}catch(T){process.stderr.write(`[greedysearch] Evidence synthesis failed: ${T.message}
|
|
451
|
+
`)}if(!P.synthesized&&G.length>0)try{N.startAction("synth-final","fallback report");let T=await B0(_1($,[{round:1,learnings:[],gaps:[],actions:[]}],G,Y,F),{timeoutMs:120000});N.endAction(),P={...P,...z0(T?.answer||"")||{}},P.synthesized=Array.isArray(P.claims)&&P.claims.length>0}catch(T){process.stderr.write(`[greedysearch] Final synthesis failed: ${T.message}
|
|
452
|
+
`)}process.stderr.write(`PROGRESS:research:simple:audit
|
|
453
|
+
`);let w=L1(P.answer||"",G),g=await A1(G,w);C1(Y,P,w);let d=$8(P.caveats||[]),f=l$({sources:G,fetchedSources:O,synthesis:P,citationAudit:w,gaps:d,questions:Y,rounds:[{round:1,actions:[],learnings:[],gaps:d}],qualityScore:P.synthesized?8:5,qualityThreshold:J,maxSources:X}),x=new Date().toISOString(),i=Date.now()-j,G0={startedAt:V,finishedAt:x,durationMs:i,rounds:1,terminationReason:"simple_single_pass"},o=null,J0;if(W){process.stderr.write(`PROGRESS:research:simple:bundle
|
|
454
|
+
`);try{o=await R1({query:$,rounds:[{round:1,actions:[],learnings:[],gaps:d,evidence:F}],sources:G,fetchedSources:O,evidenceItems:F,synthesis:P,citationAudit:w,citationUrls:g,floor:f,manifest:{...G0,engines:K$,synthesizer:"gemini",actionsRun:1,searches:1,fetches:O.length,sourcesFetched:O.filter((T)=>T?.contentChars>100).length,engineFailures:[],floorMet:f.floorMet},allGaps:d,questions:Y,outDir:K}),J0=o.sourceFiles,delete o.sourceFiles}catch(T){process.stderr.write(`[greedysearch] Research bundle write failed: ${T.message}
|
|
455
|
+
`),o={error:T.message||String(T)},J0=await e0(O)}}else J0=await e0(O);return process.stderr.write(`PROGRESS:research:done
|
|
456
|
+
`),N.endRound(),N.finish(),{query:$,_research:{mode:"simple",breadth:1,iterations:1,maxSources:X,rounds:[{round:1,actions:[],learnings:[],gaps:d,evidence:F}],learnings:[],gaps:d,evidence:F,questions:Y,questionProgress:f7(Y),qualityHistory:[P.synthesized?8:5],terminationReason:"simple_single_pass",qualityThreshold:J,floor:f,bundle:o,manifest:G0},_citationAudit:w,_citationUrls:g,_sources:G,_fetchedSources:J0,_synthesis:P,_confidence:{sourcesCount:G.length,fetchedSourceSuccessRate:O.length>0?O.filter((T)=>T.contentChars>100).length/O.length:0,agreementLevel:P.agreement?.level||"mixed",floorMet:f.floorMet}}}var S7=x7(new URL(".",import.meta.url)).replace(/^\/([A-Z]:)/,"$1"),g7=m(S7,"..","..","bin","search.mjs"),y7=m(process.cwd(),".pi","greedysearch-research"),h7=28000;function p7($){return String($||"research").toLowerCase().replaceAll(/[^a-z0-9]+/g,"-").replaceAll(/^-|-$/g,"").slice(0,60)||"research"}function C0($,Z=1/0){let X=new Set,J=[];for(let W of $||[]){let K=R(String(W||""),1000);if(!K||X.has(K))continue;if(X.add(K),J.push(K),J.length>=Z)break}return J}async function m7(...$){let{fetchMultipleSources:Z}=await Promise.resolve().then(() => (O$(),U1));return Z(...$)}async function b1(...$){let{writeSourcesToFiles:Z}=await Promise.resolve().then(() => (h$(),m2));return Z(...$)}function d7({breadth:$=3,iterations:Z=2,maxSources:X}){let J=v1($,1,5,3),W=v1(Z,1,3,2),K=v1(X??Math.max(5,J*W*2),3,12,8);return{breadth:J,iterations:W,maxSources:K}}function v1($,Z,X,J){let W=Number.parseInt(String($??""),10);if(!Number.isFinite(W))return J;return Math.min(X,Math.max(Z,W))}function l7($,Z,X,{expand:J=!0,includeOriginal:W=!0,exclude:K=[]}={}){let V=Array.isArray($?.queries)?$.queries:[],j=[],Y=new Set([...K].map((Q)=>U0(Q).toLowerCase()));for(let Q of V){let H=typeof Q==="string"?Q:Q?.query,B=typeof Q==="string"?"":Q?.researchGoal||"";q1(j,H,B,{exclude:Y})}if(W)q1(j,Z,"Original user query",{prepend:!0,exclude:Y});if(J){let Q=[{query:`${Z} official docs GitHub`,researchGoal:"Find primary project docs, repository details, and maintainer claims."},{query:`${Z} benchmarks limitations compatibility`,researchGoal:"Validate performance claims and uncover unsupported APIs or caveats."},{query:`${Z} alternatives comparison production use cases`,researchGoal:"Compare against conventional headless browsers and identify when to choose it."},{query:`${Z} anti bot detection Cloudflare screenshots visual rendering`,researchGoal:"Check automation risks, rendering gaps, screenshots, and bot-detection behavior."}];for(let H of Q){if(j.length>=X)break;q1(j,H.query,H.researchGoal,{exclude:Y})}}return j.slice(0,X)}function q1($,Z,X="",{prepend:J=!1,exclude:W=new Set}={}){if(!Z||typeof Z!=="string")return;let K=U0(Z);if(!K||W.has(K.toLowerCase())||$.some((j)=>j.query.toLowerCase()===K.toLowerCase()))return;let V={query:K,researchGoal:R(X,320)};if(J)$.unshift(V);else $.push(V)}function U0($){return c7(u7(String($)))}function u7($){let Z="",X=0;while(X<$.length){let J=$.indexOf("[",X);if(J===-1){Z+=$.slice(X);break}let W=$.indexOf("]",J+1);if(W===-1||$[W+1]!=="("||W===J+1){Z+=$.slice(X,J+1),X=J+1;continue}let K=$.indexOf(")",W+2);if(K===-1){Z+=$.slice(X,J+1),X=J+1;continue}let V=$.slice(W+2,K).trimStart();if(!V.startsWith("http://")&&!V.startsWith("https://")){Z+=$.slice(X,J+1),X=J+1;continue}Z+=$.slice(X,J),Z+=$.slice(J+1,W),X=K+1}return Z}function c7($){let Z="",X=!1;for(let J of $)if(J===" "||J==="\t"||J===`
|
|
457
|
+
`||J==="\r"){if(!X)Z+=" ";X=!0}else Z+=J,X=!1;return Z.trim()}function x1($){return new Set(String($).toLowerCase().normalize("NFD").replaceAll(/[\u0300-\u036f]/g,"").split(/[^\w]+/).filter((Z)=>Z.length>1))}function g1($,Z){let X=x1($),J=x1(Z),W=new Set([...X,...J]).size;if(W===0)return 1;let K=0;for(let V of X)if(J.has(V))K++;return K/W}function K8($,Z,{threshold:X=0.75,roundIndex:J=0,originalQuery:W=null}={}){let K=U0($).toLowerCase();if(Z.has(K))return!0;if(W&&J>0&&K===U0(W).toLowerCase())return!0;for(let V of Z)if(g1(K,V)>=X)return!0;return!1}function n7($,Z,X,J){let W=Z.map((K)=>({queries:K.queries?.map((V)=>V.query||"")||[],learnings:K.learnings||[],gaps:K.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: ${$}`,`Rounds completed: ${JSON.stringify(W,null,2)}`,`Accumulated learnings: ${JSON.stringify(X.slice(0,12),null,2)}`,`Known gaps: ${JSON.stringify(J.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(`
|
|
458
|
+
`)}function i7($,Z,X,J,W){let K=[],V=[{template:(j)=>`${j} official documentation`,label:"official docs"},{template:(j)=>`${j} GitHub issues discussions`,label:"community signals"},{template:(j)=>`${j} benchmarks performance comparison`,label:"benchmarks"},{template:(j)=>`${j} limitations risks caveats`,label:"limitations"},{template:(j)=>`${j} production deployment experience`,label:"production usage"},{template:(j)=>`${Z} ${j} counter evidence`,label:"counter-evidence"}];for(let j=0;j<$.length&&K.length<J;j++){let Y=$[j],Q=V[j%V.length],H=Q.template(Y);if(!K8(H,X,{roundIndex:W}))K.push({query:H,researchGoal:`Gap-driven: ${Y} (${Q.label})`})}return K}async function a7($,Z,X,J,W){try{let K=await B0(n7($,Z,X,J),{timeoutMs:120000}),V=D$(K,{}),j=typeof V.score==="number"?Math.min(10,Math.max(0,V.score)):W.length>0?W[W.length-1]:5,Y=Array.isArray(V.knowledgeGaps)?V.knowledgeGaps.map((N)=>String(N)).filter(Boolean).slice(0,6):[],Q=Array.isArray(V.nextActions)?V.nextActions.slice(0,5):[],H=typeof V.shouldContinue==="boolean"?V.shouldContinue:j<8,B=V.terminationReason||null;return{score:j,coverage:V.coverage||{},knowledgeGaps:Y,shouldContinue:H,nextActions:Q,terminationReason:B||(j>=8.5?"quality_threshold":null),evaluationError:""}}catch(K){return process.stderr.write(`[greedysearch] Quality evaluation failed: ${K.message}
|
|
459
|
+
`),{score:W.length>0?W[W.length-1]:5,coverage:{},knowledgeGaps:[],shouldContinue:!0,nextActions:[],terminationReason:null,evaluationError:K.message}}}function o7($){let Z={};for(let X of Object.keys($||{}).filter((J)=>!J.startsWith("_"))){let J=$?.[X];if(!J)continue;Z[X]=J.error?{status:"error",error:String(J.error)}:{status:"ok",answer:R(J.answer||"",1400),sources:Array.isArray(J.sources)?J.sources.slice(0,5).map((W)=>({title:R(W.title||"",160),url:W.url||""})):[]}}return Z}function s7($,Z,X=[],J=[],W=[]){let K=J.length>0?`
|
|
319
460
|
Known knowledge gaps to target:
|
|
320
|
-
${J.map((
|
|
461
|
+
${J.map((j)=>`- ${j}`).join(`
|
|
321
462
|
`)}`:"",V=W.length>0?`
|
|
322
463
|
Already fetched URLs (do not re-fetch):
|
|
323
|
-
${W.map((
|
|
464
|
+
${W.map((j)=>`- ${j}`).join(`
|
|
324
465
|
`)}`:"";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 ${Z} actions.`,"Avoid near-duplicate search queries and already-fetched URLs.","",`User topic: ${$}`,X.length?`
|
|
325
466
|
Prior learnings to build on:
|
|
326
|
-
${X.map((
|
|
467
|
+
${X.map((j)=>`- ${j}`).join(`
|
|
327
468
|
`)}`:"",K,V,"","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(`
|
|
328
|
-
`)}function
|
|
329
|
-
`)}
|
|
330
|
-
`)}function
|
|
331
|
-
`)}function
|
|
332
|
-
`)}async function
|
|
333
|
-
`);Q=
|
|
334
|
-
`)});let H=setTimeout(()=>{
|
|
335
|
-
`)
|
|
336
|
-
`)
|
|
337
|
-
`),"
|
|
338
|
-
`)
|
|
339
|
-
`),
|
|
469
|
+
`)}function V8($){if(!$||typeof $!=="object")return null;let Z=$.type,X=R($.researchGoal||"",320);if(Z==="search"){if($.query==null)return null;let J=U0($.query);return J?{type:"search",query:J,researchGoal:X}:null}if(Z==="fetchUrl"){if($.url==null)return null;let J=e($.url);return J?{type:"fetchUrl",url:J,researchGoal:X}:null}return null}async function t7($,{locale:Z=null,short:X=!0,usedQueries:J,usedUrls:W,maxChars:K=8000}={}){if($.type==="search"){let V=U0($.query).toLowerCase();J.add(V);try{let j=await V9($.query,{locale:Z,short:X}),Y=q0(j,$.query);return{ok:!0,action:$,result:j,sources:Y}}catch(j){return{ok:!1,action:$,error:j.message,sources:[]}}}if($.type==="fetchUrl"){let V=e($.url);if(W.has(V))return{ok:!1,action:$,error:`URL already fetched: ${V}`,sources:[]};try{let j=await r7(V,K);W.add(V);let Y=e7(V),Q={id:"",canonicalUrl:j.finalUrl||V,displayUrl:j.url||V,domain:Y,title:j.title||V,engines:["fetch"],engineCount:1,perEngine:{},sourceType:z1(Y,j.title||"",j.finalUrl||V),isOfficial:!1,smartScore:0,fetch:{attempted:!0,ok:!j.error&&(j.contentChars||0)>100,status:j.status||null,finalUrl:j.finalUrl||V,content:j.content||"",contentChars:j.contentChars||0,snippet:j.snippet||"",error:j.error||""}};return{ok:!0,action:$,result:null,sources:[Q],fetchResult:{id:Q.id,url:V,finalUrl:j.finalUrl||V,title:j.title||"",content:j.content||"",contentChars:j.contentChars||0,snippet:j.snippet||"",status:j.status||null,error:j.error||"",source:j.source||"http",duration:j.duration||0}}}catch(j){return{ok:!1,action:$,error:j.message,sources:[]}}}return{ok:!1,action:$,error:`Unknown action type: ${$.type}`,sources:[]}}async function r7($,Z){let{fetchSourceContent:X}=await Promise.resolve().then(() => (O$(),U1));return await X($,Z)}function e7($){try{return new URL($).hostname.toLowerCase().replace(/^www\./,"")}catch{return""}}async function $9($,Z){let X=[],{parseGitHubUrl:J}=await Promise.resolve().then(() => (N1(),C2));for(let W of $){if(W.type!=="fetchUrl"){X.push(W);continue}let K=J(W.url);if(!K||K.type!=="root"){X.push(W);continue}let{owner:V,repo:j}=K,Y=`https://github.com/${V}/${j}`;if(Z.has(Y))continue;let Q=[Y],H=[`${Y}/blob/main/CONTRIBUTING.md`,`${Y}/blob/master/CONTRIBUTING.md`,`${Y}/blob/main/CHANGELOG.md`,`${Y}/blob/master/CHANGELOG.md`,`${Y}/blob/main/docs/README.md`];for(let B of H){if(Q.length>=3)break;if(!Z.has(B))Q.push(B)}for(let B of Q)X.push({type:"fetchUrl",url:B,researchGoal:W.researchGoal||`Fetch GitHub content for ${V}/${j}`})}return X}function Z9($,Z){let X=z0($?.answer||"")||{},J=Array.isArray(X?.actions)?X.actions:[],W=[];for(let K of J){let V=V8(K);if(V&&W.length<Z)W.push(V)}return W}function X9($){return($||[]).map((Z)=>({type:"search",query:typeof Z==="string"?Z:Z.query,researchGoal:typeof Z==="string"?"":Z.researchGoal||""})).filter((Z)=>Z.query)}function $$($){return e($?.finalUrl||$?.canonicalUrl||$?.url||"")||$?.id||""}function j8($,Z){let X=Array.isArray($?.extractions)?$.extractions:[],J=new Map,W=new Map;for(let K of Z||[]){if(K?.id)W.set(String(K.id),K);let V=$$(K);if(V)J.set(V,K)}return X.map((K)=>{let V=W.get(String(K?.sourceId||""))||J.get(e(K?.url||"")||""),j=String(K?.sourceId||V?.id||""),Y=e(K?.url||V?.finalUrl||V?.url||""),Q=Array.isArray(K?.answers)?K.answers.map((H)=>({id:String(H?.id||""),evidence:R(H?.evidence||"",500),sourceIds:[j].filter(Boolean)})).filter((H)=>H.id):[];return{sourceId:j,url:Y,title:V?.title||K?.title||"",rational:R(K?.rational||"",700),evidence:R(K?.evidence||"",1600),summary:R(K?.summary||"",700),answers:Q,newQuestions:C0(K?.newQuestions||[],6)}}).filter((K)=>K.sourceId||K.url||K.summary||K.evidence)}function J9($,Z,X,J=new Set){let W=(Z||[]).filter((V)=>V.status!=="closed").slice(0,12).map((V)=>({id:V.id,question:V.question})),K=(X||[]).filter((V)=>V?.content||V?.snippet).filter((V)=>!J.has($$(V))).slice(0,6).map((V,j)=>({id:V.id||`F${j+1}`,title:V.title||"",url:V.finalUrl||V.url||V.canonicalUrl||"",content:R(V.content||V.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: ${$}`,`Open question ledger: ${JSON.stringify(W,null,2)}`,`Fetched sources: ${JSON.stringify(K,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(`
|
|
470
|
+
`)}async function X8({query:$,questions:Z,fetchedSources:X,extractedSourceKeys:J}){let W=(X||[]).filter((K)=>(K?.content||K?.snippet)&&!J.has($$(K)));if(W.length===0)return{evidence:[],error:""};try{let K=await B0(J9($,Z,W,J),{timeoutMs:120000}),V=D$(K,{extractions:[]}),j=j8(V,W);for(let Y of W){let Q=$$(Y);if(Q)J.add(Q)}return{evidence:j,error:""}}catch(K){return{evidence:[],error:K.message||String(K)}}}function W9($,Z,X,J,W,K,V=[]){let j=(Z||[]).filter((F)=>F.status!=="closed").slice(0,12).map((F)=>({id:F.id,question:F.question})),Y=(W||[]).filter((F)=>F?.content||F?.snippet),Q=(K||[]).filter((F)=>F?.content||F?.snippet),H=({extractionCount:F,extractionLimit:P,learningCount:w,learningLimit:g})=>{let d=Y.slice(0,F).map((x,i)=>({id:x.id||`F${i+1}`,title:x.title||"",url:x.finalUrl||x.url||x.canonicalUrl||"",content:R(x.content||x.snippet||"",P)})),f=Q.slice(0,w).map((x,i)=>({id:`F${i+1}`,title:x.title||"",url:x.finalUrl||x.url||"",snippet:R(x.content||x.snippet||"",g)}));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: ${$}`,`Open question ledger: ${JSON.stringify(j)}`,`Round queries: ${JSON.stringify(X)}`,`Question ledger: ${JSON.stringify(Z)}`,`Extracted source evidence so far: ${JSON.stringify(V.slice(-12))}`,`Engine summaries: ${JSON.stringify(J)}`,`Sources for evidence extraction (Task A): ${JSON.stringify(d)}`,`Fetched source snippets (Task B context): ${JSON.stringify(f)}`,"","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(`
|
|
471
|
+
`)},B=Math.min(4,Y.length),N=3000,G=Math.min(6,Q.length),O=2000,M=H({extractionCount:B,extractionLimit:N,learningCount:G,learningLimit:O}),D=!1,z=600;while(M.length>h7){if(N>z||O>z)N=Math.max(z,Math.floor(N/2)),O=Math.max(z,Math.floor(O/2));else if(G>1)G-=1;else if(B>1)B-=1;else if(N>1||O>1)N=Math.max(1,Math.floor(N/2)),O=Math.max(1,Math.floor(O/2));else throw Error(`[greedysearch] evidence/learning prompt exceeds Gemini input cap after source trimming: ${M.length} chars`);D=!0,M=H({extractionCount:B,extractionLimit:N,learningCount:G,learningLimit:O})}if(D)console.error(`[greedysearch] evidence/learning prompt trimmed to fit Gemini input cap: ${M.length} chars`);return M}async function K9({query:$,questions:Z,fetchedSources:X,extractedSourceKeys:J,roundQueries:W,searchSummaries:K,evidenceItems:V=[]}){let j=(X||[]).filter((N)=>(N?.content||N?.snippet)&&!J.has($$(N))),Y=[],Q="",H={learnings:[],followUpQueries:[],gaps:[]},B="";try{let N=await B0(W9($,Z,W,K,j,X,V),{timeoutMs:180000}),G=D$(N,{});Y=j8(G,j);for(let O of j){let M=$$(O);if(M)J.add(M)}H={...H,...G}}catch(N){let G=N.message||String(N);Q=G,B=G}return{evidence:Y,evidenceError:Q,learningPayload:H,learningError:B}}function _1($,Z,X,J=[],W=[]){let K=Z.flatMap((Y)=>Y.learnings||[]),V=Z.flatMap((Y)=>Y.gaps||[]),j=X.slice(0,12).map((Y)=>({id:Y.id,title:Y.title,domain:Y.domain,url:Y.canonicalUrl,type:Y.sourceType,engines:Y.engines,fetch:Y.fetch?.attempted?{ok:Y.fetch.ok,snippet:R(Y.fetch.snippet||"",1200),publishedTime:Y.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: ${$}`,`Learnings: ${JSON.stringify(K,null,2)}`,`Known gaps/caveats: ${JSON.stringify(V,null,2)}`,`Question ledger: ${JSON.stringify(J,null,2)}`,`Goal-based extracted evidence: ${JSON.stringify(W.slice(-20),null,2)}`,`Source registry: ${JSON.stringify(j,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(`
|
|
472
|
+
`)}function k1($,Z=[],X=[],J=[]){let W=Z.slice(0,12).map((Y)=>({id:Y.id,title:Y.title,domain:Y.domain,url:Y.canonicalUrl,type:Y.sourceType,engines:Y.engines})),K=J.slice(-20),V=new Set;for(let Y of K)for(let Q of Y.answers||[])if(Q?.id)V.add(Q.id);let j=(X||[]).filter((Y)=>Y.status!=="closed").map((Y)=>({id:Y.id,question:Y.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: ${$}`,`Per-source extracted evidence: ${JSON.stringify(K,null,2)}`,`Source registry: ${JSON.stringify(W,null,2)}`,`Questions already answered by the evidence: ${JSON.stringify(Array.from(V))}`,`Questions still open after this evidence: ${JSON.stringify(j)}`,"","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(`
|
|
473
|
+
`)}async function V9($,{locale:Z=null,short:X=!0}={}){let J=[g7,"all","--inline","--stdin","--fast"];if(!X)J.push("--full");if(Z)J.push("--locale",Z);return new Promise((W,K)=>{let V=b7(H0(),J,{stdio:["pipe","pipe","pipe"],env:{...process.env,GREEDY_SEARCH_RESEARCH_CHILD:"1"}});V.stdin.write($),V.stdin.end();let j="",Y="",Q="";V.stdout.on("data",(B)=>j+=B),V.stderr.on("data",(B)=>{Y+=B,Q+=B.toString();let N=Q.split(`
|
|
474
|
+
`);Q=N.pop()||"";for(let G of N)if(H9(G))process.stderr.write(`${G}
|
|
475
|
+
`)});let H=setTimeout(()=>{V.kill(),K(Error(`research child search timed out for: ${$}`))},140000);V.on("close",(B)=>{if(clearTimeout(H),B!==0){K(Error(Y.trim()||`search child exited with code ${B}`));return}try{W(JSON.parse(j.trim()))}catch{K(Error(`Invalid JSON from research child: ${j.slice(0,200)}`))}})})}function j9($){let Z=new Map;for(let X of $.flat()){let J=e(X.canonicalUrl||X.url);if(!J)continue;let W=Z.get(J);if(!W){Z.set(J,{...X,canonicalUrl:J});continue}W.engines=[...new Set([...W.engines||[],...X.engines||[]])],W.engineCount=W.engines.length,W.smartScore=Math.max(W.smartScore||0,X.smartScore||0)}return Array.from(Z.values()).sort((X,J)=>{let W=l0(J)-l0(X);if(W!==0)return W;return(X.domain||"").localeCompare(J.domain||"")}).slice(0,12).map((X,J)=>({...X,id:`S${J+1}`}))}var Y9=r.join("|"),Q9=new RegExp(`^\\[(${Y9})\\]`);function H9($){return/^PROGRESS:/.test($)||/^\[greedysearch\]/.test($)||Q9.test($)||/^GreedySearch Chrome/.test($)||/^Launching GreedySearch Chrome/.test($)||/^Headless mode/.test($)||/^Ready\.?$/.test($)}function D$($,Z={}){return z0($?.answer||"")||Z}function L1($,Z){if(!$||!Array.isArray(Z))return{cited:[],missing:[],unfetched:[],ok:!0};let X=/\b[SF](\d+)\b/g,J=new Set,W;while((W=X.exec($))!==null)J.add(`S${W[1]}`),J.add(`F${W[1]}`);let K=new Map;for(let Q of Z){let H=Q?.id;if(H)K.set(H,Q)}let V=Array.from(J),j=[],Y=[];for(let Q of V){let H=K.get(Q);if(!H){let B=Q.match(/^(S|F)(\d+)$/);if(B){let N=parseInt(B[2],10)-1;if(N>=0&&N<Z.length){let G=Z[N];if(G){if(!(G.fetch?.ok||G.content&&G.content.length>100||G.contentChars&&G.contentChars>100))Y.push(Q);continue}}}j.push(Q)}else if(!(H.fetch?.ok||H.content&&H.content.length>100||H.contentChars&&H.contentChars>100))Y.push(Q)}return{cited:V,missing:j,unfetched:Y,ok:j.length===0}}async function B9($,{timeoutMs:Z=6000,concurrency:X=4}={}){let J=Math.max(1,Math.floor(X||1)),W=($||[]).filter((N)=>N?.id&&(N?.canonicalUrl||N?.finalUrl||N?.url));if(W.length===0)return{reachable:[],dead:[],skipped:[],ok:!0};let K=[],V=[],j=[],Y=Array(W.length),Q=0;async function H(){while(!0){let N=Q++;if(N>=W.length)return;let G=W[N];try{let O=G.fetch?.finalUrl||G.canonicalUrl||G.finalUrl||G.url;if(!O){Y[N]={id:G.id,url:"",status:"skipped"};continue}try{let M=new URL(O);if(M.protocol!=="http:"&&M.protocol!=="https:"){Y[N]={id:G.id,url:O,status:"skipped"};continue}}catch{Y[N]={id:G.id,url:O,status:"skipped"};continue}try{let M=new AbortController,D=setTimeout(()=>M.abort(),Z);try{let z=await fetch(O,{method:"HEAD",redirect:"follow",signal:M.signal,headers:{"User-Agent":"Mozilla/5.0 (compatible; GreedySearch/2.0; +https://github.com/apmantza/greedysearch-dm)"}});clearTimeout(D);let F=z.status>=200&&z.status<400,P=[401,403,405,429].includes(z.status),w="dead";if(F)w="reachable";else if(P)w="skipped";Y[N]={id:G.id,url:O,status:w,httpStatus:z.status,reason:P?"bot-protected-or-head-disallowed":void 0}}catch(z){clearTimeout(D),Y[N]={id:G.id,url:O,status:"dead",error:z.name==="AbortError"?"timeout":z.message}}}catch(M){Y[N]={id:G.id,url:O,status:"dead",error:M.message}}}catch(O){Y[N]={id:"?",url:"",status:"dead",error:O?.message||"unknown"}}}}let B=Math.min(W.length,J);await Promise.all(Array.from({length:B},()=>H()));for(let N of Y)if(N.status==="reachable")K.push(N);else if(N.status==="dead")V.push(N);else j.push(N);return{reachable:K,dead:V,skipped:j,ok:V.length===0}}async function A1($,Z=null){process.stderr.write(`PROGRESS:research:check-urls
|
|
476
|
+
`);try{let X=new Set(Z?.cited||[]),J=X.size?($||[]).filter((K)=>X.has(K?.id)):$,W=await B9(J,{timeoutMs:6000,concurrency:4});if(!W.ok)process.stderr.write(`[greedysearch] ${W.dead.length} dead citation URL(s) detected
|
|
477
|
+
`);return W}catch(X){return process.stderr.write(`[greedysearch] URL reachability check failed: ${X.message}
|
|
478
|
+
`),null}}function l$({sources:$=[],fetchedSources:Z=[],synthesis:X={},citationAudit:J=null,gaps:W=[],questions:K=[],rounds:V=[],qualityScore:j=0,qualityThreshold:Y=8.5,maxSources:Q=8,requireCitations:H=!0,requireQuestions:B=!0}={}){let N=Z.filter((f)=>f?.fetch?.ok||(f?.contentChars||0)>100||String(f?.content||"").length>100),G=$.filter((f)=>["official-docs","repo","maintainer-blog","academic"].includes(String(f?.sourceType||""))),O=Array.isArray(X?.claims)?X.claims:[],M=J?J.cited?.length||0:0,D=S1(K),z=(K||[]).filter((f)=>!f.createdRound||f.reason==="Original research question"),F=S1(z),P=(V||[]).length,w=Math.min(4,Math.max(2,Number(Q)||8)),g=P<=1?Math.min(2,w):w,d={roundsRun:V.length>=1,fetchedSources:N.length>=g,primarySources:G.length>=1,qualityScore:j>=Math.min(Y,8)||H&&O.length>0&&M>0,claimsExtracted:!H||O.length>0,citationsPresent:!H||M>0,citationsValid:!H||J?.ok===!0,unfetchedCitations:!H||(J?.unfetched||[]).length===0,requiredQuestionsClosed:!B||F.open===0};return{floorMet:Object.values(d).every(Boolean),checks:d,metrics:{fetchedOk:N.length,primarySources:G.length,claims:O.length,cited:M,gaps:W.length,openQuestions:D.open,closedQuestions:D.closed,totalQuestions:D.total,openRequiredQuestions:F.open,closedRequiredQuestions:F.closed,totalRequiredQuestions:F.total,qualityScore:j,minFetched:g}}}function J8($,Z){let X=new Map;for(let J of Z||[]){let W=e(J?.canonicalUrl||J?.finalUrl||J?.url);if(W&&J?.id)X.set(W,J.id)}return($||[]).map((J,W)=>{let K=e(J?.finalUrl||J?.canonicalUrl||J?.url);return{...J,id:J?.id||X.get(K)||`F${W+1}`}})}function T1($){return[{id:"Q1",question:R(U0($),320),status:"open",reason:"Original research question",evidence:[],sourceIds:[]}]}function G9($){let Z=0;for(let X of $||[]){let J=Number.parseInt(String(X.id||"").replace(/^Q/i,""),10);if(Number.isFinite(J))Z=Math.max(Z,J)}return`Q${Z+1}`}function Y8($,Z){let X=U0(Z).toLowerCase();return($||[]).find((J)=>J.question?.toLowerCase()===X||g1(J.question||"",X)>=0.82)}function E1($,Z,{reason:X="",round:J=null}={}){let W=R(U0(Z),320);if(!W)return null;let K=Y8($,W);if(K)return K;let V={id:G9($),question:W,status:"open",reason:R(X,240),createdRound:J,evidence:[],sourceIds:[]};return $.push(V),V}function c$($,Z,{evidence:X="",sourceIds:J=[],round:W=null}={}){let K=$.find((V)=>V.id===Z)||Y8($,Z);if(!K)return null;if(K.status="closed",K.closedRound=K.closedRound||W,X)K.evidence=C0([...K.evidence||[],X],4);if(Array.isArray(J))K.sourceIds=C0([...K.sourceIds||[],...J],8);return K}function S1($){let Z=$.length,X=$.filter((J)=>J.status==="closed").length;return{total:Z,closed:X,open:Math.max(0,Z-X)}}function u$($,{roundNumber:Z,actions:X=[],learningPayload:J={}}={}){for(let Y of X){let Q=Y?.action||Y,H=Q?.researchGoal&&Q.researchGoal!=="Original user query"?Q.researchGoal:Q?.query||Q?.url||"";if(H)E1($,H,{reason:"Planned research action",round:Z})}let W=5,K=$.filter((Y)=>Y.status==="open"&&Y.reason==="Discovered gap/follow-up");if(K.length>W){let Y=K.sort((Q,H)=>(Q.createdRound||0)-(H.createdRound||0)).slice(0,K.length-W);for(let Q of Y)Q.status="resolved",Q.closedRound=Z,Q.evidence=C0([...Q.evidence||[],"Auto-resolved to cap open-question ledger"],4)}let V=Array.isArray(J.answeredQuestions)?J.answeredQuestions:[];for(let Y of V){if(typeof Y==="string"){c$($,Y,{round:Z});continue}let Q=Y?.id||Y?.question;if(!Q&&Y?.question){let H=E1($,Y.question,{reason:"Answered during learning extraction",round:Z});if(H)c$($,H.id,{round:Z});continue}c$($,Q,{evidence:Y?.evidence||Y?.answer||"",sourceIds:Array.isArray(Y?.sourceIds)?Y.sourceIds:[],round:Z})}let j=Array.isArray(J.newQuestions)?J.newQuestions:[];for(let Y of j)E1($,Y,{reason:"Discovered gap/follow-up",round:Z});return $}function N9($,Z){if(!Array.isArray($)||$.length===0)return[];let X=["arxiv.org","semanticscholar.org","doi.org"],J=new Set,W=[];for(let K of $){let V=K?.canonicalUrl||K?.finalUrl||K?.url||"";if(!V)continue;let j="";try{j=new URL(V).hostname.toLowerCase().replace(/^www\./,"")}catch{continue}if(!X.some((Q)=>j===Q||j.endsWith(`.${Q}`)))continue;if(Z.has(V)||J.has(V))continue;J.add(V);let Y=V.includes("/pdf/")?V.replace(/\/pdf\//,"/html/").replace(/\.pdf$/i,""):V;W.push({url:Y,label:K?.title||K?.id||j})}return W.slice(0,2)}function C1($,Z,X){if(!Z?.answer||X?.ok!==!0)return $;let J=Array.isArray(Z.claims)?Z.claims:[],W=Array.isArray(X.cited)?X.cited:[];if(J.length===0||W.length===0)return $;for(let K of $){if(K.status==="closed")continue;let V=null,j=0;for(let Y of J){let Q=g1(K.question||"",Y.claim||"");if(Q>j)j=Q,V=Y}if(K.id==="Q1"||j>=0.18)c$($,K.id,{evidence:V?.claim||"Answered in final cited synthesis",sourceIds:Array.isArray(V?.sourceIds)?V.sourceIds:W.slice(0,4)})}return $}function O9($){if(!$.length)return"No tracked questions.";return $.map((Z)=>{let X=Z.sourceIds?.length?` (${Z.sourceIds.join(", ")})`:"";return`- [${Z.status==="closed"?"x":" "}] ${Z.id}: ${Z.question}${X}`}).join(`
|
|
479
|
+
`)}function f1($,Z="None recorded."){let X=C0($);return X.length?X.map((J)=>`- ${J}`).join(`
|
|
480
|
+
`):Z}function M9($,{query:Z,rounds:X,sources:J,fetchedSources:W,citationAudit:K,citationUrls:V,floor:j,manifest:Y}){let Q=(W||[]).filter((M)=>M?.contentChars>100||M?.fetch?.ok),H=(J||[]).filter((M)=>["official-docs","repo","maintainer-blog","academic"].includes(String(M?.sourceType||""))),B=new Set(K?.cited||[]),N=(J||[]).filter((M)=>B.has(M?.id)),G=[`# Provenance: ${Z}`,"",`- **Date:** ${Y?.startedAt||new Date().toISOString()}`,`- **Duration:** ${Y?.durationMs?`${(Y.durationMs/1000).toFixed(1)}s`:"unknown"}`,`- **Mode:** ${Y?.terminationReason==="simple_single_pass"?"simple (single-pass)":"iterative"}`,`- **Rounds:** ${Y?.rounds||X?.length||1}`,"","## Sources","",`- **Consulted:** ${J?.length||0}`,`- **Fetched successfully:** ${Q.length}`,`- **Primary sources:** ${H.length}`,`- **Cited in report:** ${N.length}`,""];if(N.length>0){G.push("### Cited sources","");for(let M of N){let D=M.canonicalUrl||M.finalUrl||M.url||"",z=M.fetch?.ok?"✓":"✗";G.push(`- **${M.id}:** [${M.title||D}](${D}) (${M.sourceType||"unknown"}, fetched: ${z})`)}G.push("")}if(V&&(V.reachable.length>0||V.dead.length>0)){if(G.push("## URL reachability",""),V.dead.length>0){G.push(""),G.push("**Dead links:**");for(let M of V.dead)G.push(`- ${M.id}: ${M.url} (${M.httpStatus||M.error||"unknown"})`)}if(V.reachable.length>0)G.push(""),G.push(`**Reachable:** ${V.reachable.length}/${V.reachable.length+V.dead.length}`);G.push("")}let O=!K?"NOT CHECKED":K.ok&&(V?.ok??!0)?"PASS":K.ok===!1?"FAIL (missing citations)":"FAIL (dead links)";if(G.push("## Verification","",`- **Citations:** ${K?.ok?"PASS":`FAIL — missing: ${(K?.missing||[]).join(", ")}`}`,`- **URL reachability:** ${V?V.ok?"PASS":`FAIL — ${V.dead.length} dead`:"SKIPPED"}`,`- **Floor:** ${j?.floorMet?"PASS":"PARTIAL"}`,`- **Overall:** ${O}`,""),j?.checks){G.push("## Floor checks","");for(let[M,D]of Object.entries(j.checks))G.push(`- [${D?"x":" "}] ${M}`);G.push("")}j0(m($,"provenance.md"),G.join(`
|
|
481
|
+
`),"utf8")}async function R1({query:$,rounds:Z,sources:X,fetchedSources:J,evidenceItems:W=[],synthesis:K,citationAudit:V,floor:j,manifest:Y,allGaps:Q=[],questions:H=[],citationUrls:B=null,outDir:N=null}){let G=new Date().toISOString().replaceAll(/[:.]/g,"-").slice(0,19),O=N||m(y7,`${G}_${p7($)}`),M=m(O,"reports"),D=m(O,"sources"),z=m(O,"data");I1(M,{recursive:!0}),I1(D,{recursive:!0}),I1(z,{recursive:!0});let F=await b1(J,D),P=C0([...Q,...Z.flatMap((w)=>w.gaps||[])]);j0(m(O,"STATUS.md"),[j.floorMet?"STATUS: DONE":"STATUS: PARTIAL","",`Query: ${$}`,`Stop reason: ${Y.terminationReason||"max_rounds"}`,"","## Deterministic floor checks",...Object.entries(j.checks).map(([w,g])=>`- [${g?"x":" "}] ${w}`),"","## Questions",O9(H),"","## Open gaps",f1(P),""].join(`
|
|
482
|
+
`),"utf8"),j0(m(O,"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(`
|
|
483
|
+
`),"utf8"),j0(m(M,"SUMMARY.md"),String(K.answer||""),"utf8"),j0(m(M,"CLAIMS.md"),["# Key claims","",...Array.isArray(K.claims)&&K.claims.length?K.claims.map((w)=>{let g=Array.isArray(w.sourceIds)?w.sourceIds.join(", "):"";return`- ${w.claim||""} (${w.support||"support unknown"}${g?`; ${g}`:""})`}):["No structured claims were extracted."],""].join(`
|
|
484
|
+
`),"utf8"),j0(m(M,"EVIDENCE.md"),["# Extracted evidence","",...W.length?W.map((w)=>[`## ${w.sourceId||w.url||"Source"}`,w.url?`<${w.url}>`:"",w.rational?`**Rational:** ${w.rational}`:"",w.evidence?`**Evidence:** ${w.evidence}`:"",w.summary?`**Summary:** ${w.summary}`:"",""].filter(Boolean).join(`
|
|
340
485
|
`)):["No goal-based evidence was extracted."],""].join(`
|
|
341
|
-
`),"utf8"),
|
|
342
|
-
`),"utf8"),
|
|
343
|
-
`),"utf8")
|
|
344
|
-
`)
|
|
345
|
-
`)
|
|
346
|
-
`)
|
|
347
|
-
`)
|
|
348
|
-
`);
|
|
349
|
-
`)
|
|
350
|
-
`),process.stderr.write(`[greedysearch]
|
|
351
|
-
`);
|
|
352
|
-
`)}
|
|
353
|
-
`)
|
|
354
|
-
`)
|
|
355
|
-
`)
|
|
356
|
-
`)
|
|
357
|
-
`)}let
|
|
358
|
-
`)
|
|
359
|
-
`),
|
|
360
|
-
`);
|
|
361
|
-
`)
|
|
362
|
-
`);let
|
|
363
|
-
`)
|
|
364
|
-
`),
|
|
365
|
-
`)
|
|
366
|
-
`)
|
|
367
|
-
`)
|
|
368
|
-
`)
|
|
369
|
-
`)
|
|
370
|
-
|
|
486
|
+
`),"utf8"),j0(m(M,"GAPS.md"),["# Gaps and caveats","","## Caveats",f1(K.caveats||[]),"","## Research gaps",f1(P),""].join(`
|
|
487
|
+
`),"utf8"),j0(m(z,"manifest.json"),JSON.stringify({...Y,floor:j,citationAudit:V},null,2),"utf8"),j0(m(z,"rounds.json"),JSON.stringify(Z,null,2),"utf8"),j0(m(z,"sources.json"),JSON.stringify(X,null,2),"utf8"),j0(m(z,"questions.json"),JSON.stringify(H,null,2),"utf8"),j0(m(z,"evidence.json"),JSON.stringify(W,null,2),"utf8"),j0(m(D,"index.md"),["# Source index","",...F.map((w)=>{let g=w.title||w.url,d=w.finalUrl||w.url,f=w.contentPath?` — ${w.contentPath}`:"";return`- ${w.id||"?"}: [${g}](${d})${f}`}),""].join(`
|
|
488
|
+
`),"utf8");try{M9(O,{query:$,rounds:Z,sources:X,fetchedSources:J,citationAudit:V,citationUrls:B,floor:j,manifest:Y})}catch(w){process.stderr.write(`[greedysearch] Provenance sidecar write failed (non-critical): ${w.message}
|
|
489
|
+
`)}return{dir:O,statusPath:m(O,"STATUS.md"),summaryPath:m(M,"SUMMARY.md"),manifestPath:m(z,"manifest.json"),provenancePath:m(O,"provenance.md"),sourceCount:F.length,sourceFiles:F}}async function Q8({query:$,breadth:Z,iterations:X,maxSources:J,locale:W=null,short:K=!1,qualityThreshold:V=8.5,writeBundle:j=process.env.GREEDY_RESEARCH_BUNDLE!=="0",researchOutDir:Y=null}={}){let Q=d7({breadth:Z,iterations:X,maxSources:J}),H=Z!==void 0&&Z!==null,B=X!==void 0&&X!==null;if(!H&&!B)try{let _=await e2($);if(process.stderr.write(`[greedysearch] Complexity: ${_.complexity} (${_.reasoning})
|
|
490
|
+
`),_.complexity==="simple")return process.stderr.write(`[greedysearch] Simple query detected — using fast single-pass path
|
|
491
|
+
`),Z8({query:$,locale:W,maxSources:Math.min(J??5,5),qualityThreshold:V,writeBundle:j,researchOutDir:Y});if(!H)Q.breadth=_.suggestedBreadth;if(!B)Q.iterations=_.suggestedIterations}catch(_){process.stderr.write(`[greedysearch] Scale classification failed, using defaults: ${_.message}
|
|
492
|
+
`)}let G=[],O=[],M=[],D=T1($),z=null,F=[],P=[],w=[],g=new Set,d=new Set,f=new Set,x=[],i="max_rounds",G0=new Date().toISOString(),o=Date.now(),J0=0,T=0,$0=0,c=[],s=d$({totalActions:Q.iterations*Q.breadth,totalRounds:Q.iterations,totalFetches:Q.iterations,silent:process.env.GREEDY_RESEARCH_QUIET==="1"});s.startRound(1),process.stderr.write(`[greedysearch] Research mode: breadth ${Q.breadth}, iterations ${Q.iterations}, qualityThreshold ${V}, engines ${K$.join(",")}, synthesizer gemini
|
|
493
|
+
`);for(let _=0;_<Q.iterations;_++){let A=_+1,h=Math.max(1,Math.ceil(Q.breadth/2**_));if(process.stderr.write(`PROGRESS:research:round-${A}:planning
|
|
494
|
+
`),!z)try{let U=await B0(s7($,h,O,M,[...f]),{timeoutMs:120000}),E=Z9(U,h);if(_===0)E.unshift({type:"search",query:$,researchGoal:"Original user query"});E=await $9(E,f),z=E}catch(U){process.stderr.write(`[greedysearch] Action planning failed, using fallback queries: ${U.message}
|
|
495
|
+
`);let E=l7(null,$,h,{includeOriginal:_===0,exclude:d});z=X9(E)}let Y0=(z||[]).filter((U)=>{if(U.type==="search"){let E=!K8(U.query,d,{roundIndex:_,originalQuery:$});if(!E)process.stderr.write(`[greedysearch] Novelty gate rejected search: ${U.query}
|
|
496
|
+
`);return E}if(U.type==="fetchUrl"){let E=!f.has(U.url);if(!E)process.stderr.write(`[greedysearch] Novelty gate rejected fetch: ${U.url}
|
|
497
|
+
`);return E}return!1}).slice(0,h),S=N9(F,f);if(!Y0.some((U)=>U.type==="fetchUrl")&&S.length>0){let U=S[0];Y0.push({type:"fetchUrl",url:U.url,researchGoal:`Direct fetch of known academic source: ${U.label||U.url}`}),process.stderr.write(`[greedysearch] Forced fetchUrl for academic source: ${U.url}
|
|
498
|
+
`)}let p=Array(Y0.length),l=Math.min(3,Y0.length),Q0=0;async function f0(){while(!0){let U=Q0++;if(U>=Y0.length)return;let E=Y0[U];process.stderr.write(`PROGRESS:research:round-${A}:action-${U+1}/${Y0.length}
|
|
499
|
+
`),process.stderr.write(`[greedysearch] Action ${U+1}/${Y0.length} [${E.type}]: ${(E.query||E.url).slice(0,80)}
|
|
500
|
+
`),s.startAction(E.type,(E.query||E.url||"").slice(0,60));let t=await t7(E,{locale:W,short:K,usedQueries:d,usedUrls:f,maxChars:8000});s.endAction(),p[U]=t}}await Promise.all(Array.from({length:l},()=>f0()));let w0=[];for(let U=0;U<Y0.length;U++){let E=Y0[U],t=p[U];if(w0.push(t),J0++,E.type==="search")T++;if(E.type==="fetchUrl")$0++,s.endFetch(t.ok);if(!t.ok)c.push({round:A,type:E.type,target:E.query||E.url,error:t.error}),process.stderr.write(`[greedysearch] Action failed: ${t.error}
|
|
501
|
+
`)}let h1=w0.filter((U)=>U.action.type==="search"),p1=w0.filter((U)=>U.action.type==="fetchUrl");u$(D,{roundNumber:A,actions:w0}),F=j9([F,h1.flatMap((U)=>U.sources||[]),p1.flatMap((U)=>U.sources||[])]);for(let U of p1)if(U.fetchResult)P.push(U.fetchResult);P=W8(P);let i$=Math.max(0,Q.maxSources-P.filter((U)=>U?.content||U?.contentChars>100).length);if(i$>0&&F.length>0){process.stderr.write(`PROGRESS:research:round-${A}:fetching
|
|
502
|
+
`);let U=new Set,E=(_0)=>{try{return e(_0||"")}catch{return""}};for(let _0 of P)for(let U$ of[_0?.url,_0?.finalUrl,_0?.canonicalUrl]){let i0=E(U$);if(i0)U.add(i0)}let t=F.filter((_0)=>{let U$=[_0?.canonicalUrl,_0?.finalUrl,_0?.url].map((i0)=>E(i0)).filter(Boolean);return U$.length>0&&U$.every((i0)=>!U.has(i0))}),O8=await m7(t,Math.min(i$,t.length),8000,Math.min(3,i$||1));P=W8([...P,...O8]),F=t0(F,P)}P=J8(P,F);let N8=w0.map((U)=>({query:U.action.query||U.action.url||"",researchGoal:U.action.researchGoal||""}));process.stderr.write(`PROGRESS:research:round-${A}:evidence
|
|
503
|
+
`),process.stderr.write(`PROGRESS:research:round-${A}:learning
|
|
504
|
+
`);let z$=await K9({query:$,questions:D,fetchedSources:P,extractedSourceKeys:g,roundQueries:N8,searchSummaries:h1.map((U)=>({query:U.action.query,researchGoal:U.action.researchGoal,error:U.error||"",engines:o7(U.result)})),evidenceItems:w}),c0={evidence:z$.evidence,error:z$.evidenceError};if(c0.error)process.stderr.write(`[greedysearch] Evidence extraction failed: ${c0.error}
|
|
505
|
+
`);w=[...w,...c0.evidence];for(let U of c0.evidence)u$(D,{roundNumber:A,learningPayload:{answeredQuestions:U.answers||[],newQuestions:U.newQuestions||[]}});let{learningPayload:n0,learningError:a$}=z$;if(a$)process.stderr.write(`[greedysearch] Learning extraction failed: ${a$}
|
|
506
|
+
`);let m1=Array.isArray(n0.learnings)?n0.learnings.map((U)=>String(U)).filter(Boolean).slice(0,8):[],o$=Array.isArray(n0.gaps)?n0.gaps.map((U)=>String(U)).filter(Boolean).slice(0,6):[];if(O=C0([...O,...m1]),M=C0([...M,...o$]),u$(D,{roundNumber:A,actions:[],learningPayload:n0,gaps:o$}),G.push({round:A,actions:w0.map((U)=>({type:U.action.type,query:U.action.query||"",url:U.action.url||"",researchGoal:U.action.researchGoal||"",error:U.error||"",sourceCount:U.sources?.length||0})),learnings:m1,gaps:o$,evidence:c0.evidence,evidenceError:c0.error,learningError:a$}),process.stderr.write(`PROGRESS:research:round-${A}:evaluating
|
|
507
|
+
`),s.endRound(),A<Q.iterations)s.startRound(A+1);let K0=A===Q.iterations?{score:x.length>0?x[x.length-1]:5,coverage:{},knowledgeGaps:[],shouldContinue:!1,nextActions:[],terminationReason:null,evaluationError:""}:await a7($,G,O,M,x);x.push(K0.score),M=C0([...M,...K0.knowledgeGaps||[]]),u$(D,{roundNumber:A,gaps:K0.knowledgeGaps||[]});let d1=l$({sources:F,fetchedSources:P,gaps:M,questions:D,rounds:G,qualityScore:K0.score,qualityThreshold:V,maxSources:Q.maxSources,requireCitations:!1,requireQuestions:!1});if(process.stderr.write(`[greedysearch] Quality score round ${A}: ${K0.score.toFixed(1)} (shouldContinue: ${K0.shouldContinue}, floor: ${d1.floorMet})
|
|
508
|
+
`),K0.score>=V&&d1.floorMet&&(!K0.shouldContinue||K0.terminationReason==="quality_threshold")){i=K0.terminationReason||"quality_threshold",process.stderr.write(`[greedysearch] Research floor reached (score: ${K0.score.toFixed(1)}). Terminating early.
|
|
509
|
+
`);break}let b0=Math.max(1,Math.ceil(h/2)),P0=(n0.followUpQueries||[]).map((U)=>({type:"search",query:U0(String(U)),researchGoal:"Follow-up from learning extraction"})).filter((U)=>U.query&&U.query.toLowerCase()!==$.toLowerCase()).slice(0,b0);if(P0.length<b0&&K0.nextActions.length>0){let U=K0.nextActions.map((t)=>V8(t)).filter(Boolean);P0=[...P0,...U].slice(0,b0)}if(P0.length<b0&&M.length>0){let U=i7(M,$,d,b0-P0.length,_+1),E=U.map((t)=>({type:"search",query:t.query,researchGoal:t.researchGoal}));if(P0=[...P0,...E].slice(0,b0),U.length>0)process.stderr.write(`[greedysearch] Generated ${U.length} gap-driven fallback actions.
|
|
510
|
+
`)}z=P0.length>=b0?P0:null}process.stderr.write(`PROGRESS:research:final-report
|
|
511
|
+
`);let q={answer:O.length?O.map((_)=>`- ${_}`).join(`
|
|
512
|
+
`):"Research completed, but no structured learnings were extracted.",agreement:{level:"mixed",summary:"Research synthesis fallback."},differences:[],caveats:[],claims:[],recommendedSources:F.slice(0,4).map((_)=>_.id),synthesized:!1};try{let _=await B0(_1($,G,F,D,w),{timeoutMs:180000}),A=D$(_,{}),h=Array.isArray(A?.claims)&&A.claims.length>0;q={...q,...A,rawAnswer:_.answer||"",geminiSources:_.sources||[],synthesized:h}}catch(_){process.stderr.write(`[greedysearch] Final report failed: ${_.message}
|
|
513
|
+
`),q.error=_.message}if(!(q.synthesized===!0&&Array.isArray(q.claims)&&q.claims.length>0)&&w.length>0){process.stderr.write(`[greedysearch] Falling back to evidence-based synthesis (no per-round learnings).
|
|
514
|
+
`);try{let _=k1($,F,D,w),A=await B0(_,{timeoutMs:180000}),h=D$(A,{});q={...q,...h,rawAnswer:A.answer||q.answer||"",geminiSources:A.sources||q.geminiSources||[],synthesized:!0,synthesisMode:"evidence_fallback"}}catch(_){process.stderr.write(`[greedysearch] Evidence-based synthesis failed: ${_.message}
|
|
515
|
+
`),q.evidenceFallbackError=_.message}}let b=new Date().toISOString(),W0=Date.now()-o,k=x.at(-1)||0;P=J8(P,F),process.stderr.write(`PROGRESS:research:audit-citations
|
|
516
|
+
`);let I=L1(q.answer||"",F),X$=await A1(F,I);C1(D,q,I);let a=l$({sources:F,fetchedSources:P,synthesis:q,citationAudit:I,gaps:M,questions:D,rounds:G,qualityScore:k,qualityThreshold:V,maxSources:Q.maxSources});if(a.floorMet&&i==="max_rounds")i="done_floor_met";else if(!a.floorMet&&i==="quality_threshold")i="max_rounds_floor_unmet";let C={startedAt:G0,finishedAt:b,durationMs:W0,engines:K$,synthesizer:"gemini",rounds:G.length,actionsRun:J0,searches:T,fetches:$0,sourcesFetched:P.filter((_)=>_?.contentChars>100).length,engineFailures:c,terminationReason:i,floorMet:a.floorMet},v=null,L;if(j){process.stderr.write(`PROGRESS:research:bundle
|
|
517
|
+
`);try{v=await R1({query:$,rounds:G,sources:F,fetchedSources:P,evidenceItems:w,synthesis:q,citationAudit:I,citationUrls:X$,floor:a,manifest:C,allGaps:M,questions:D,outDir:Y}),L=v.sourceFiles,delete v.sourceFiles}catch(_){v={error:_.message||String(_)},L=await b1(P)}}else L=await b1(P);return process.stderr.write(`PROGRESS:research:done
|
|
518
|
+
`),s.finish(),{query:$,_research:{mode:"iterative",breadth:Q.breadth,iterations:Q.iterations,maxSources:Q.maxSources,rounds:G,learnings:O,gaps:M,evidence:w,questions:D,questionProgress:S1(D),qualityHistory:x,terminationReason:i,qualityThreshold:V,floor:a,bundle:v,manifest:C},_citationAudit:I,_citationUrls:X$,_sources:F,_fetchedSources:L,_synthesis:q,_confidence:{sourcesCount:F.length,fetchedSourceSuccessRate:P.length>0?Number((P.filter((_)=>_.contentChars>100).length/P.length).toFixed(2)):0,agreementLevel:q.agreement?.level||"mixed",floorMet:a.floorMet}}}function W8($){let Z=new Map;for(let V of $){let j=V?.id||e(V?.finalUrl||V?.url||"");if(!j)continue;let Y=Z.get(j);if(!Y||(V.contentChars||0)>(Y.contentChars||0))Z.set(j,V)}let X=new Map;function J(V){let j=X.get(V);if(!j){let Y=String(V.content||V.snippet||"");j={length:Y.length,tokens:x1(Y.slice(0,4000))},X.set(V,j)}return j}function W(V,j){let Y=0,Q=V.size<=j.size?V:j,H=V.size<=j.size?j:V;for(let N of Q)if(H.has(N))Y++;let B=V.size+j.size-Y;if(B===0)return 1;return Y/B}let K=[];for(let V of Z.values()){let j=J(V),Y=K.findIndex((Q)=>{let H=X.get(Q);if(j.length<400||H.length<400)return!1;return W(j.tokens,H.tokens)>=0.9});if(Y===-1){K.push(V);continue}if((V.contentChars||0)>(K[Y].contentChars||0))K[Y]=V}return K}import D9 from"node:http";function H8($,Z=1000){return new Promise((X)=>{let J=D9.get($,(W)=>{let K="";W.on("data",(V)=>K+=V),W.on("end",()=>X({ok:W.statusCode===200,body:K}))});J.on("error",()=>X({ok:!1})),J.setTimeout(Z,()=>{J.destroy(),X({ok:!1})})})}async function B8($){try{let Z=await H8(`http://localhost:${$}/json/version`);if(!Z.ok)return;let X=JSON.parse(Z.body),J=await H8(`http://localhost:${$}/json/list`);if(!J.ok)return;let K=JSON.parse(J.body).find((Q)=>Q.type==="page")?.id;if(!K)return;let V=X.webSocketDebuggerUrl;if(typeof V!=="string")return;let j=new URL(V);if(j.hostname!=="localhost"&&j.hostname!=="127.0.0.1")return;if(!/^ws:\/\/localhost:\d+/.test(`ws://${j.host}`))return;let Y=new WebSocket(`ws://localhost:${$}${j.pathname}`);await new Promise((Q)=>{let H=!1,B=setTimeout(()=>N(),5000),N=()=>{if(H)return;H=!0,clearTimeout(B);try{Y.close()}catch{}Q()};Y.onopen=()=>{try{Y.send(JSON.stringify({id:1,method:"Browser.getWindowForTarget",params:{targetId:K}}))}catch{N()}},Y.onmessage=(G)=>{try{let O=JSON.parse(G.data);if(O.id===1&&O.result?.windowId)Y.send(JSON.stringify({id:2,method:"Browser.setWindowBounds",params:{windowId:O.result.windowId,bounds:{windowState:"minimized"}}}));else if(O.id===2)N();else if(O.id===1)N()}catch{N()}},Y.onerror=N})}catch{}}var P9=n$(w9(),".config","greedysearch"),G8=n$(P9,"config.json");function _9(){try{if(U9(G8))return JSON.parse(F9(G8,"utf8"))}catch{}return{}}function Z$($){try{z9(t1,`${JSON.stringify({at:new Date().toISOString(),...$})}
|
|
519
|
+
`,"utf8")}catch{}}async function k9(){return new Promise(($)=>{let Z="";if(process.stdin.setEncoding("utf8"),process.stdin.on("data",(X)=>Z+=X),process.stdin.on("end",()=>$(Z.trim())),process.stdin.isTTY)$("")})}async function L9(){let $=process.argv.slice(2);if($[0]==="--dm-print-helper-paths"){let k=o0(import.meta.url);console.log(JSON.stringify({launchScript:n$(k,"launch.mjs"),searchScript:n$(k,"search.mjs"),perplexityExtractor:s0("perplexity.mjs",{moduleDir:k})}));return}if($.length<2||$[0]==="--help")process.stderr.write(`${['Usage: node search.mjs <engine> "<query>"',"","Engines: all, perplexity (p), google (g), chatgpt (gpt), gemini (gem), semantic-scholar (s2), logically (log), bing (b)","","Flags:"," --synthesize For engine=all: synthesize fetched sources"," --synthesizer <engine> Synthesis engine (default from ~/.dm/greedyconfig)"," --fast Legacy quick mode: no source fetching or synthesis"," --depth <mode> Legacy: fast|standard|deep aliases, or research"," --deep-research Deprecated alias for --research"," --research Iterative query/learnings loop (alias: --depth research)"," --breadth <n> Research mode query breadth, 1-5 (default: 3)"," --iterations <n> Research mode rounds, 1-3 (default: 2)"," --max-sources <n> Research mode fetched source cap, 3-12"," --research-out-dir <dir> Write research bundle to a specific directory"," --no-research-bundle Disable the default .dm/greedysearch-research bundle"," --fetch-top-source Fetch content from top source"," --inline Output JSON to stdout (for piping)"," --locale <lang> Force results language (en, de, fr, etc.)"," --visible Always use visible Chrome for this search"," --always-visible Alias for --visible"," --stdin Read query from stdin (avoids command-line leakage)","","Environment:"," GREEDY_SEARCH_VISIBLE Set to 1 to show Chrome window (disables headless)"," GREEDY_SEARCH_ALWAYS_VISIBLE Set to 1 to force visible mode for all runs"," GREEDY_SEARCH_LOCALE Default locale (default: en)","","Examples:",' node search.mjs all "Node.js streams" # Grounded: engines + fetched sources',' node search.mjs all "Node.js streams" --synthesize # Add Gemini synthesis',' node search.mjs all "quick check" --fast # Legacy fast: no sources/synthesis',' node search.mjs all "browser automation" --research --breadth 3 --iterations 2',' node search.mjs p "what is memoization" # Single engine search'].join(`
|
|
371
520
|
`)}
|
|
372
|
-
`),process.exit(1);if($.includes("--visible")||$.includes("--always-visible")||process.env.GREEDY_SEARCH_ALWAYS_VISIBLE==="1")process.env.GREEDY_SEARCH_VISIBLE="1",process.env.GREEDY_SEARCH_ALWAYS_VISIBLE="1",delete process.env.GREEDY_SEARCH_HEADLESS;else if(process.env.GREEDY_SEARCH_VISIBLE!=="1")process.env.GREEDY_SEARCH_HEADLESS="1";await
|
|
373
|
-
`);if(
|
|
374
|
-
`);let
|
|
375
|
-
`);let
|
|
376
|
-
`),{engine:A
|
|
377
|
-
`);if(
|
|
378
|
-
${
|
|
379
|
-
`)}}let
|
|
380
|
-
`);for(let h of
|
|
381
|
-
`);await
|
|
382
|
-
`);else if(
|
|
383
|
-
`);else process.stderr.write(`[greedysearch] ⚠️ Recovery attempt did not extract an answer — ${
|
|
384
|
-
`);if(
|
|
385
|
-
`);let
|
|
521
|
+
`),process.exit(1);if($.includes("--visible")||$.includes("--always-visible")||process.env.GREEDY_SEARCH_ALWAYS_VISIBLE==="1")process.env.GREEDY_SEARCH_VISIBLE="1",process.env.GREEDY_SEARCH_ALWAYS_VISIBLE="1",delete process.env.GREEDY_SEARCH_HEADLESS;else if(process.env.GREEDY_SEARCH_VISIBLE!=="1")process.env.GREEDY_SEARCH_HEADLESS="1";await H$(),f$();let X=$.indexOf("--depth"),J=X!==-1&&$[X+1]?$[X+1].toLowerCase():null,W=$.find((k)=>!k.startsWith("--"))?.toLowerCase(),K=$.includes("--research")||$.includes("--deep-research")||J==="research",V=$.includes("--fast")||J==="fast",j=J==="standard"||J==="deep"||$.includes("--deep"),Y=W==="all"&&!V,Q=W==="all"&&!V&&($.includes("--synthesize")||j),H=J==="deep"||$.includes("--deep");if($.includes("--deep-research"))process.stderr.write(`[greedysearch] --deep-research is deprecated; use --research or --depth research
|
|
522
|
+
`);if(j)process.stderr.write(`[greedysearch] depth fast|standard|deep is deprecated; use default grounded search plus --synthesize when needed
|
|
523
|
+
`);let B=$.indexOf("--synthesizer"),N=M$(B===-1?r1:$[B+1]),O=!$.includes("--full"),M=$.includes("--fetch-top-source"),D=$.includes("--inline"),z=$.indexOf("--breadth"),F=$.indexOf("--iterations"),P=$.indexOf("--max-sources"),w=z===-1?void 0:$[z+1],g=F===-1?void 0:$[F+1],d=P===-1?void 0:$[P+1],f=$.indexOf("--research-out-dir"),x=f===-1?void 0:$[f+1],i=!$.includes("--no-research-bundle"),G0=$.indexOf("--out"),o=G0===-1?null:$[G0+1],J0=$.indexOf("--locale"),T=process.env.GREEDY_SEARCH_LOCALE,$0=_9(),c="en";if(J0!==-1&&$[J0+1])c=$[J0+1];else if(T)c=T;else if($0.locale)c=$0.locale;let s=$.filter((k,I)=>k!=="--full"&&k!=="--short"&&k!=="--fast"&&k!=="--fetch-top-source"&&k!=="--synthesize"&&k!=="--deep-research"&&k!=="--deep"&&k!=="--research"&&k!=="--inline"&&k!=="--stdin"&&k!=="--headless"&&k!=="--visible"&&k!=="--always-visible"&&k!=="--depth"&&k!=="--synthesizer"&&k!=="--out"&&k!=="--locale"&&k!=="--breadth"&&k!=="--iterations"&&k!=="--max-sources"&&k!=="--research-out-dir"&&k!=="--no-research-bundle"&&k!=="--help"&&(X===-1||I!==X+1)&&(B===-1||I!==B+1)&&(G0===-1||I!==G0+1)&&(J0===-1||I!==J0+1)&&(z===-1||I!==z+1)&&(F===-1||I!==F+1)&&(P===-1||I!==P+1)&&(f===-1||I!==f+1)),q=s[0]?.toLowerCase(),F0=$.includes("--stdin"),b;if(F0)b=await k9();else b=s.slice(1).join(" ");if(K){if(q!=="all")process.stderr.write(`[greedysearch] Research mode uses all engines; ignoring engine "${q}".
|
|
524
|
+
`);let k=await Q8({query:m$(b),breadth:w,iterations:g,maxSources:d,locale:c,short:O,writeBundle:i,researchOutDir:x});u0(k,o,{inline:D,synthesize:!0,query:b});return}if(q==="all"){await y(["list"]);let k={perplexity:"https://www.perplexity.ai/",google:"https://www.google.com/",chatgpt:"https://chatgpt.com/",gemini:"https://gemini.google.com/app","semantic-scholar":"https://www.semanticscholar.org/",semanticscholar:"https://www.semanticscholar.org/",s2:"https://www.semanticscholar.org/",logically:"https://logically.app/research-assistant/"},I=await Promise.all(r.map((a)=>T0(k[a])));await y(["list"]);let X$=(a)=>{if(!V)return 70000;return a==="chatgpt"?60000:35000};try{let a=await Promise.allSettled(r.map((L,_)=>v0(N0[L],m$(b),I[_],O,X$(L),c).then((A)=>{return process.stderr.write(`PROGRESS:${L}:done
|
|
525
|
+
`),{engine:L,...A}}).catch((A)=>{throw A}))),C={};for(let L=0;L<a.length;L++){let _=a[L];if(_.status==="fulfilled")C[_.value.engine]=_.value;else{let A=_.reason,h=A?.message||"unknown error";if(C[r[L]]={error:h},A?.lastStage)process.stderr.write(`[greedysearch] ${r[L]} failed at stage '${A.lastStage}': ${h}
|
|
526
|
+
`);if(A?.partialErr)process.stderr.write(`[greedysearch] ${r[L]} tail stderr:
|
|
527
|
+
${A.partialErr}
|
|
528
|
+
`)}}let v=u2(C);if(v.length>0&&process.env.GREEDY_SEARCH_VISIBLE!=="1"){Z$({scope:"all",phase:"start",engines:v,reasons:Object.fromEntries(v.map((h)=>[h,{error:C[h]?.error||null,envelope:C[h]?._envelope||null}]))}),process.stderr.write(`[greedysearch] \uD83D\uDD13 Headless ${v.join(", ")} search hit timeout/verification/antibot signals — retrying visible to establish cookies...
|
|
529
|
+
`);for(let h of v)process.stderr.write(`[greedysearch] ${h} recovery starting in visible mode...
|
|
530
|
+
`);await x$(I),await m0(),process.env.GREEDY_SEARCH_VISIBLE="1",delete process.env.GREEDY_SEARCH_HEADLESS,await H$(),await y(["list"]);let L=[],_=!1,A=0;for(let h=0;h<v.length;h++){let Z0=await T0();L.push(Z0)}try{let h=await Promise.allSettled(v.map((S,M0)=>v0(N0[S],b,L[M0],O,null,c).then((p)=>({engine:S,...p})).catch((p)=>({engine:S,error:p.message})))),Z0=[],Y0=[];for(let S of h)if(S.status==="fulfilled"&&!S.value.error)C[S.value.engine]=S.value,A++,process.stderr.write(`PROGRESS:${S.value.engine}:done
|
|
531
|
+
`);else if(S.status==="fulfilled"){if(C[S.value.engine]=S.value,Z0.push(S.value.engine),P1(S.value.error))Y0.push(S.value.engine)}if(A>0)process.stderr.write(`[greedysearch] ✅ ${A}/${v.length} engine(s) recovered — cookies cached for future headless runs.
|
|
532
|
+
`);else process.stderr.write(`[greedysearch] ⚠️ Recovery attempt did not extract an answer — ${v.join(", ")} may still need manual verification or a DOM fallback.
|
|
533
|
+
`);if(Z0.length>0){process.stderr.write(`[greedysearch] Second visible retry for ${Z0.join(", ")} — Turnstile may have resolved on first attempt...
|
|
534
|
+
`);let S=await Promise.allSettled(Z0.map((p)=>{let l=v.indexOf(p);return v0(N0[p],b,L[l],O,null,c).then((Q0)=>({engine:p,...Q0})).catch((Q0)=>({engine:p,error:Q0.message}))})),M0=[];for(let p of S)if(p.status==="fulfilled"&&!p.value.error)C[p.value.engine]=p.value,A++,process.stderr.write(`PROGRESS:${p.value.engine}:done
|
|
386
535
|
`),process.stderr.write(`[greedysearch] ✅ ${p.value.engine} recovered on second visible retry.
|
|
387
|
-
`);else
|
|
388
|
-
`);
|
|
389
|
-
`)
|
|
390
|
-
`)
|
|
391
|
-
`);
|
|
392
|
-
`)
|
|
393
|
-
`);
|
|
394
|
-
`)}
|
|
395
|
-
`)
|
|
536
|
+
`);else M0.push(p.value?.engine||"unknown");Z0.length=0,Z0.push(...M0)}if(Z$({scope:"all",phase:Z0.length>0?"needs-human":"success",engines:v,results:Object.fromEntries(v.map((S)=>[S,{mode:C[S]?._envelope?.mode||null,durationMs:C[S]?._envelope?.durationMs||null,lastStage:C[S]?._envelope?.lastStage||null,error:C[S]?.error||null}]))}),Z0.length>0){for(let l of Z0)process.stderr.write(`PROGRESS:${l}:needs-human
|
|
537
|
+
`);let M0=(await Promise.all(Z0.map(async(l)=>{let Q0=L[v.indexOf(l)],f0=await F1({tab:Q0,engine:l}).catch((w0)=>({cleared:!1,reason:w0.message||String(w0)}));return{engine:l,tab:Q0,...f0}}))).filter((l)=>l.cleared);if(M0.length>0)process.stderr.write(`[greedysearch] \uD83D\uDD04 Auto-resuming ${M0.map((l)=>l.engine).join(", ")} on cleared tabs...
|
|
538
|
+
`),await Promise.allSettled(M0.map(async(l)=>{let Q0=N0[l.engine];try{let f0=await v0(Q0,b,l.tab,O,null,c);C[l.engine]=f0,process.stderr.write(`PROGRESS:${l.engine}:done
|
|
539
|
+
`)}catch(f0){process.stderr.write(`[greedysearch] ⚠️ Resume extraction failed for ${l.engine}: ${f0.message}
|
|
540
|
+
`)}}));let p=Z0.filter((l)=>!M0.find((Q0)=>Q0.engine===l));if(p.length===0)_=!1;else _=!0,C._needsHumanVerification={engines:p,message:"Visible Chrome is open with the engine page loaded. Solve the Turnstile checkbox or other challenge in the visible window to store cookies. Cookies persist for future runs."},process.stderr.write(`[greedysearch] \uD83D\uDD13 ${p.join(", ")} still blocked — keeping visible Chrome open. Solve the challenge in the window to store cookies, then rerun.
|
|
541
|
+
`)}}finally{if(_)y1().catch(()=>{});else await x$(L),process.stderr.write(`[greedysearch] Switching back to headless Chrome...
|
|
542
|
+
`),await m0(),delete process.env.GREEDY_SEARCH_VISIBLE,process.env.GREEDY_SEARCH_HEADLESS="1",await H$(),await y(["list"])}I.length=0}for(let L of r){if(!C[L]?.error)continue;if(v.includes(L)){if(process.env.GREEDY_SEARCH_VISIBLE==="1")process.stderr.write(`PROGRESS:${L}:${P1(C[L].error)?"needs-human":"error"}
|
|
543
|
+
`);continue}process.stderr.write(`PROGRESS:${L}:error
|
|
544
|
+
`)}if(C._sources=q0(C,b),Y&&C._sources.length>0){process.stderr.write(`PROGRESS:source-fetch:start
|
|
545
|
+
`);let L=await N$(C._sources,5,8000);C._sources=t0(C._sources,L),C._fetchedSources=e0(L),process.stderr.write(`PROGRESS:source-fetch:done
|
|
396
546
|
`)}if(Q){process.stderr.write(`PROGRESS:synthesis:start
|
|
397
|
-
`),process.stderr.write(`[greedysearch] Synthesizing results with ${
|
|
398
|
-
`);let
|
|
399
|
-
`)}catch(
|
|
400
|
-
`),
|
|
401
|
-
Available: ${Object.keys(
|
|
402
|
-
`),process.exit(1);try{let
|
|
403
|
-
`),await
|
|
404
|
-
`)
|
|
547
|
+
`),process.stderr.write(`[greedysearch] Synthesizing results with ${N}...
|
|
548
|
+
`);let L=null;try{L=await T0(o2(N));let _=await t2(b,C,{grounded:H,tabPrefix:L,visible:process.env.GREEDY_SEARCH_VISIBLE==="1",synthesizer:N});C._synthesis={..._,synthesized:!0},process.stderr.write(`PROGRESS:synthesis:done
|
|
549
|
+
`)}catch(_){process.stderr.write(`[greedysearch] Synthesis failed: ${_.message}
|
|
550
|
+
`),C._synthesis={error:_.message,synthesized:!1,synthesizedBy:N}}finally{if(L)await I0(L)}}if(M){let L=A9(C);if(L)C._topSource=await r0(L.canonicalUrl||L.url)}if(!V)C._confidence=a2(C);u0(C,o,{inline:D,synthesize:Q,query:b});return}finally{await x$(I)}}let W0=N0[q];if(!W0)process.stderr.write(`Unknown engine: "${q}"
|
|
551
|
+
Available: ${Object.keys(N0).join(", ")}
|
|
552
|
+
`),process.exit(1);try{let k=await v0(W0,m$(b),null,O,null,c);if(M&&k.sources?.length>0)k.topSource=await r0(k.sources[0].url);u0(k,o,{inline:D,synthesize:!1,query:b})}catch(k){let I=W0.includes("bing")?"bing":W0.includes("perplexity")?"perplexity":W0.includes("chatgpt")?"chatgpt":W0.includes("semantic-scholar")?"semantic-scholar":W0.includes("logically")?"logically":null;if(I&&process.env.GREEDY_SEARCH_VISIBLE!=="1"&&c2(k)){Z$({scope:"single",phase:"start",engines:[I],reasons:{[I]:{error:k.message||null,envelope:k.envelope||null,lastStage:k.lastStage||null}}}),process.stderr.write(`[greedysearch] \uD83D\uDD13 ${I} blocked in headless — retrying visible to establish cookies...
|
|
553
|
+
`),await m0(),process.env.GREEDY_SEARCH_VISIBLE="1",delete process.env.GREEDY_SEARCH_HEADLESS,await H$(),await y(["list"]);let a=await T0(),C=!1;try{let v=await v0(W0,b,a,O,null,c);if(Z$({scope:"single",phase:"success",engines:[I],result:{engine:I,mode:v._envelope?.mode||null,durationMs:v._envelope?.durationMs||null,lastStage:v._envelope?.lastStage||null}}),M&&v.sources?.length>0)v.topSource=await r0(v.sources[0].url);u0(v,o,{inline:D,synthesize:!1,query:b});return}catch(v){if(Z$({scope:"single",phase:"needs-human",engines:[I],result:{engine:I,error:v.message||String(v),envelope:v.envelope||null}}),(await F1({tab:a,engine:I}).catch((_)=>({cleared:!1,reason:_.message||String(_)}))).cleared){process.stderr.write(`[greedysearch] \uD83D\uDD04 Auto-resuming ${I} extraction on the now-cleared tab...
|
|
554
|
+
`);try{let _=await v0(W0,b,a,O,null,c);if(Z$({scope:"single",phase:"success-after-poll",engines:[I],result:{engine:I,mode:_._envelope?.mode||null,durationMs:_._envelope?.durationMs||null,lastStage:_._envelope?.lastStage||null}}),M&&_.sources?.length>0)_.topSource=await r0(_.sources[0].url);u0(_,o,{inline:D,synthesize:!1,query:b});return}catch(_){process.stderr.write(`[greedysearch] ⚠️ Resume extraction failed: ${_.message}
|
|
555
|
+
`)}}C=!0,u0({query:b,error:v.message,_needsHumanVerification:{engines:[I],message:"Visible Chrome is open with the engine page loaded. Solve the Turnstile checkbox or other challenge to store cookies. Cookies persist for future runs."}},o,{inline:D,synthesize:!1,query:b});return}finally{if(!C)await I0(a),await m0(),delete process.env.GREEDY_SEARCH_VISIBLE,process.env.GREEDY_SEARCH_HEADLESS="1";else y1().catch(()=>{})}}process.stderr.write(`Error: ${k.message}
|
|
556
|
+
`),process.exit(1)}}function A9($){if(Array.isArray($._sources)&&$._sources.length>0)return $._sources[0];for(let Z of["perplexity","google","bing"]){let X=$[Z];if(X?.sources?.length>0)return X.sources[0]}return null}async function y1(){if(process.env.GREEDY_SEARCH_HEADLESS==="1")return;await B8(n)}L9().finally(async()=>{f$(),y1().catch(()=>{})});
|