@duckmind/dm-darwin-arm64 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,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{randomInt as
|
|
3
|
-
`)[0]?.slice(0,8);if(!
|
|
4
|
-
`)}return
|
|
2
|
+
import{randomInt as tt}from"node:crypto";import{spawn as et}from"node:child_process";import{basename as it}from"node:path";import{dirname as ot,join as ut}from"node:path";import{fileURLToPath as lt}from"node:url";function rt(n=process.env,t=process.execPath){let e=n.GREEDY_SEARCH_NODE||n.NODE_BINARY||n.NODE;if(e?.trim())return e.trim();let o=it(t||"").toLowerCase();if(o==="node"||o==="node.exe")return t;return"node"}var ft=ot(lt(import.meta.url)),at=ut(ft,"..","bin","cdp.mjs"),gt=new Set(["list","snap","eval","shot","html","nav","net","click","clickxy","type","loadall","evalraw","browse","stop","--tab"]);function ht(n){if(!Array.isArray(n)||n.length===0)throw Error("cdp: args must be a non-empty array");if(n[0]==="test")return n.map((t,e)=>yn(t,e));if(!gt.has(n[0]))throw Error(`cdp: unknown subcommand '${n[0]}'`);return n.map((t,e)=>yn(t,e))}function yn(n,t){if(typeof n!=="string")throw Error(`cdp: argv[${t}] must be a string (got ${typeof n})`);if(n.includes("\x00"))throw Error(`cdp: argv[${t}] contains a null byte`);return n}function f(n,t=30000){return nn(n,null,t)}function nn(n,t=null,e=30000){let o=ht(n);return new Promise((i,r)=>{let u=et(rt(),[at,...o],{stdio:[t==null?"ignore":"pipe","pipe","pipe"]});if(t!=null)u.stdin.write(t),u.stdin.end();let l="",a="";u.stdout.on("data",(h)=>l+=h),u.stderr.on("data",(h)=>a+=h);let g=setTimeout(()=>{u.kill(),r(Error(`cdp timeout: ${n[0]}`))},e);u.on("close",(h)=>{if(clearTimeout(g),h===0)i(l.trim());else r(Error(a.trim()||`cdp exit ${h}`))})})}function _n(n,t){let e=(u)=>String(u??"").replace(/\s+/g," ").trim(),o=e(n),i=e(t);if(!i)return!1;if(o.length<Math.ceil(i.length*0.8))return!1;let r=Math.min(40,i.length);return o.includes(i.slice(0,r))&&o.includes(i.slice(-r))}async function vn(n){if(n)return n;let t=(await f(["list"])).split(`
|
|
3
|
+
`)[0]?.slice(0,8);if(!t)throw Error("No Chrome tabs found. Is Chrome running with --remote-debugging-port=9222?");let e=await f(["evalraw",t,"Target.createTarget",'{"url":"about:blank"}']),o;try{o=JSON.parse(e)}catch(u){throw Error(`Target.createTarget returned invalid JSON: ${u.message}`)}let{targetId:i}=o;if(!i)throw Error("Target.createTarget did not return a targetId");await f(["list"]);let r=i.slice(0,8);try{await $n(r)}catch(u){process.stderr.write(`[getOrOpenTab] stealth injection failed: ${u.message}
|
|
4
|
+
`)}return r}async function $n(n){await f(["evalraw",n,"Page.addScriptToEvaluateOnNewDocument",JSON.stringify({source:`
|
|
5
5
|
(function() {
|
|
6
6
|
// ── Runtime.enable / CDP detection masking ──────────────
|
|
7
7
|
try { delete window.__REBROWSER_RUNTIME_ENABLE; } catch(_) {}
|
|
@@ -12,40 +12,62 @@ import{randomInt as hg}from"node:crypto";import{spawn as og}from"node:child_proc
|
|
|
12
12
|
try { delete window._phantom; } catch(_) {}
|
|
13
13
|
try { delete window.Buffer; } catch(_) {}
|
|
14
14
|
|
|
15
|
-
// Real Chrome without automation
|
|
16
|
-
// A literal false
|
|
17
|
-
//
|
|
18
|
-
|
|
15
|
+
// Real Chrome without automation should not expose navigator.webdriver at all.
|
|
16
|
+
// A literal false or an own-property getter returning undefined is itself a
|
|
17
|
+
// common stealth tell; remove both instance and prototype properties when the
|
|
18
|
+
// descriptor is configurable (as it is with --disable-blink-features).
|
|
19
|
+
try { delete navigator.webdriver; } catch(_) {}
|
|
20
|
+
try { delete Navigator.prototype.webdriver; } catch(_) {}
|
|
19
21
|
Object.defineProperty(navigator, 'vendor', { get: () => 'Google Inc.', configurable: true });
|
|
20
22
|
Object.defineProperty(navigator, 'platform', { get: () => 'Win32', configurable: true });
|
|
21
23
|
Object.defineProperty(navigator, 'maxTouchPoints', { get: () => 0, configurable: true });
|
|
22
24
|
Object.defineProperty(navigator, 'pdfViewerEnabled', { get: () => true, configurable: true });
|
|
25
|
+
Object.defineProperty(navigator, 'productSub', { get: () => '20030107', configurable: true });
|
|
26
|
+
Object.defineProperty(navigator, 'product', { get: () => 'Gecko', configurable: true });
|
|
27
|
+
var __greedyMimeTypes = null;
|
|
28
|
+
function __makeMimeTypes() {
|
|
29
|
+
var pdf = { type: 'application/pdf', suffixes: 'pdf', description: 'Portable Document Format', enabledPlugin: null };
|
|
30
|
+
var textPdf = { type: 'text/pdf', suffixes: 'pdf', description: 'Portable Document Format', enabledPlugin: null };
|
|
31
|
+
try { Object.setPrototypeOf(pdf, MimeType.prototype); } catch(_) {}
|
|
32
|
+
try { Object.setPrototypeOf(textPdf, MimeType.prototype); } catch(_) {}
|
|
33
|
+
var m = [pdf, textPdf];
|
|
34
|
+
try { Object.setPrototypeOf(m, MimeTypeArray.prototype); } catch(_) {}
|
|
35
|
+
m.item = function item(i) { return this[i] || null; };
|
|
36
|
+
m.namedItem = function namedItem(name) { return Array.prototype.find.call(this, function(x) { return x && x.type === name; }) || null; };
|
|
37
|
+
return m;
|
|
38
|
+
}
|
|
23
39
|
Object.defineProperty(navigator, 'plugins', {
|
|
24
40
|
get: () => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
41
|
+
__greedyMimeTypes = __greedyMimeTypes || __makeMimeTypes();
|
|
42
|
+
var plugin0 = { name: 'Chrome PDF Plugin', filename: 'internal-pdf-viewer', description: 'Portable Document Format' };
|
|
43
|
+
var plugin1 = { name: 'Chrome PDF Viewer', filename: 'mhjfbmdgcfjbbpaeojofohoefgiehjai', description: '' };
|
|
44
|
+
var plugin2 = { name: 'Native Client', filename: 'internal-nacl-plugin', description: '' };
|
|
45
|
+
try { Object.setPrototypeOf(plugin0, Plugin.prototype); } catch(_) {}
|
|
46
|
+
try { Object.setPrototypeOf(plugin1, Plugin.prototype); } catch(_) {}
|
|
47
|
+
try { Object.setPrototypeOf(plugin2, Plugin.prototype); } catch(_) {}
|
|
48
|
+
var p = [plugin0, plugin1, plugin2];
|
|
49
|
+
p.item = function item(i) { return this[i] || null; };
|
|
50
|
+
p.namedItem = function namedItem(name) { return Array.prototype.find.call(this, function(x) { return x && x.name === name; }) || null; };
|
|
51
|
+
p.refresh = function refresh() {};
|
|
52
|
+
try { Object.setPrototypeOf(p, PluginArray.prototype); } catch(_) {}
|
|
53
|
+
try {
|
|
54
|
+
__greedyMimeTypes[0].enabledPlugin = p[0];
|
|
55
|
+
__greedyMimeTypes[1].enabledPlugin = p[0];
|
|
56
|
+
} catch(_) {}
|
|
31
57
|
return p;
|
|
32
58
|
},
|
|
59
|
+
configurable: true,
|
|
33
60
|
});
|
|
34
61
|
Object.defineProperty(navigator, 'mimeTypes', {
|
|
35
62
|
get: () => {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
{ type: 'text/pdf', suffixes: 'pdf', description: 'Portable Document Format', enabledPlugin: null },
|
|
39
|
-
];
|
|
40
|
-
m.item = function(i) { return m[i] || null; };
|
|
41
|
-
m.namedItem = function(name) { return m.find(function(x) { return x.type === name; }) || null; };
|
|
42
|
-
return m;
|
|
63
|
+
__greedyMimeTypes = __greedyMimeTypes || __makeMimeTypes();
|
|
64
|
+
return __greedyMimeTypes;
|
|
43
65
|
},
|
|
44
66
|
configurable: true,
|
|
45
67
|
});
|
|
46
68
|
Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'], configurable: true });
|
|
47
69
|
try {
|
|
48
|
-
Object.defineProperty(navigator, 'connection', { get: () => ({ effectiveType: '4g', rtt: 50, downlink: 10, saveData: false }), configurable: true });
|
|
70
|
+
Object.defineProperty(navigator, 'connection', { get: () => ({ effectiveType: '4g', rtt: 50, downlink: 10, downlinkMax: Infinity, saveData: false }), configurable: true });
|
|
49
71
|
} catch(_) {}
|
|
50
72
|
if (!navigator.mediaDevices) {
|
|
51
73
|
Object.defineProperty(navigator, 'mediaDevices', {
|
|
@@ -61,6 +83,18 @@ import{randomInt as hg}from"node:crypto";import{spawn as og}from"node:child_proc
|
|
|
61
83
|
configurable: true,
|
|
62
84
|
});
|
|
63
85
|
}
|
|
86
|
+
// ── Missing platform APIs (headless often lacks these) ─
|
|
87
|
+
try {
|
|
88
|
+
if (!navigator.share) {
|
|
89
|
+
navigator.share = function() { return Promise.reject(new Error('NotAllowedError')); };
|
|
90
|
+
}
|
|
91
|
+
} catch(_) {}
|
|
92
|
+
try {
|
|
93
|
+
if (!navigator.contentIndex) {
|
|
94
|
+
Object.defineProperty(navigator, 'contentIndex', { get: () => ({ add: function() {}, delete: function() {}, getAll: function() { return Promise.resolve([]); } }), configurable: true });
|
|
95
|
+
}
|
|
96
|
+
} catch(_) {}
|
|
97
|
+
|
|
64
98
|
if (!window.chrome) {
|
|
65
99
|
window.chrome = {
|
|
66
100
|
app: { isInstalled: false, InstallState: {}, RunningState: {} },
|
|
@@ -68,8 +102,8 @@ import{randomInt as hg}from"node:crypto";import{spawn as og}from"node:child_proc
|
|
|
68
102
|
OnInstalledReason: {}, OnRestartRequiredReason: {}, PlatformArch: {}, PlatformNaclArch: {}, PlatformOs: {}, RequestUpdateCheckStatus: {},
|
|
69
103
|
connect: () => ({}), sendMessage: () => {}, onMessage: { addListener: () => {} }
|
|
70
104
|
},
|
|
71
|
-
loadTimes: ()
|
|
72
|
-
csi: ()
|
|
105
|
+
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' }; },
|
|
106
|
+
csi: function() { var t = Date.now(); return { onloadT: t - 2000, startE: t - 5000, pageT: 'back', tran: 2 }; },
|
|
73
107
|
};
|
|
74
108
|
}
|
|
75
109
|
var __greedyNativeFns = [];
|
|
@@ -90,6 +124,19 @@ import{randomInt as hg}from"node:crypto";import{spawn as og}from"node:child_proc
|
|
|
90
124
|
return getParam.call(this, p);
|
|
91
125
|
});
|
|
92
126
|
} catch(_) {}
|
|
127
|
+
// ── WebGL readPixels noise ──────────────────────────
|
|
128
|
+
// CreepJS and other fingerprinters draw content with WebGL and read back the
|
|
129
|
+
// rendered pixels. Adding subtle noise breaks rendering-based fingerprinting.
|
|
130
|
+
try {
|
|
131
|
+
var origReadPixels = WebGLRenderingContext.prototype.readPixels;
|
|
132
|
+
WebGLRenderingContext.prototype.readPixels = __markNative(function readPixels(x, y, width, height, format, type, pixels) {
|
|
133
|
+
var result = origReadPixels.call(this, x, y, width, height, format, type, pixels);
|
|
134
|
+
if (pixels && pixels.length > 0) {
|
|
135
|
+
pixels[0] ^= 1;
|
|
136
|
+
}
|
|
137
|
+
return result;
|
|
138
|
+
});
|
|
139
|
+
} catch(_) {}
|
|
93
140
|
Object.defineProperty(navigator, 'hardwareConcurrency', { get: () => 8, configurable: true });
|
|
94
141
|
Object.defineProperty(navigator, 'deviceMemory', { get: () => 8, configurable: true });
|
|
95
142
|
|
|
@@ -97,7 +144,7 @@ import{randomInt as hg}from"node:crypto";import{spawn as og}from"node:child_proc
|
|
|
97
144
|
// Headless rendering engines produce slightly different canvas output
|
|
98
145
|
// than headed Chrome. Subtle noise breaks hash-based fingerprinting.
|
|
99
146
|
try {
|
|
100
|
-
var __canvasNoise = ((Date.now()
|
|
147
|
+
var __canvasNoise = ((Date.now() & 0xFF) | 1);
|
|
101
148
|
var origFill = CanvasRenderingContext2D.prototype.fillText;
|
|
102
149
|
CanvasRenderingContext2D.prototype.fillText = __markNative(function fillText() {
|
|
103
150
|
this.globalAlpha = 0.9995;
|
|
@@ -116,15 +163,39 @@ import{randomInt as hg}from"node:crypto";import{spawn as og}from"node:child_proc
|
|
|
116
163
|
HTMLCanvasElement.prototype.toDataURL = __markNative(function toDataURL() {
|
|
117
164
|
var ctx = this.getContext('2d');
|
|
118
165
|
if (ctx) {
|
|
119
|
-
//
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
166
|
+
// Spread noise across canvas to break hash-based fingerprinting.
|
|
167
|
+
// Uses a deterministic pattern so it's consistent per page load
|
|
168
|
+
// but varies between sessions.
|
|
169
|
+
var w = this.width, h = this.height;
|
|
170
|
+
if (w > 0 && h > 0) {
|
|
171
|
+
var imgData = ctx.getImageData(0, 0, Math.min(w, 4), Math.min(h, 4));
|
|
172
|
+
if (imgData && imgData.data) {
|
|
173
|
+
for (var __i = 0; __i < imgData.data.length; __i += 4) {
|
|
174
|
+
imgData.data[__i] ^= (__canvasNoise + __i) & 0xFF;
|
|
175
|
+
}
|
|
176
|
+
ctx.putImageData(imgData, 0, 0);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
123
179
|
}
|
|
124
180
|
return origToDataURL.apply(this, arguments);
|
|
125
181
|
});
|
|
126
182
|
} catch(_) {}
|
|
127
183
|
|
|
184
|
+
// ── AudioContext fingerprint noise ────────────────────
|
|
185
|
+
// Headless Chrome's AudioContext produces slightly different output.
|
|
186
|
+
// Subtle noise breaks audio-based fingerprinting.
|
|
187
|
+
try {
|
|
188
|
+
var __audioSeed = ((Date.now() & 0x1F) | 1);
|
|
189
|
+
var origGetChannelData = AudioBuffer.prototype.getChannelData;
|
|
190
|
+
AudioBuffer.prototype.getChannelData = __markNative(function getChannelData(channel) {
|
|
191
|
+
var data = origGetChannelData.call(this, channel);
|
|
192
|
+
for (var __i = 0; __i < data.length; __i += 64) {
|
|
193
|
+
data[__i] *= 0.99999;
|
|
194
|
+
}
|
|
195
|
+
return data;
|
|
196
|
+
});
|
|
197
|
+
} catch(_) {}
|
|
198
|
+
|
|
128
199
|
// ── window outer dimensions ──────────────────────────
|
|
129
200
|
// outerWidth/Height = 0 in headless — a well-known bot signal.
|
|
130
201
|
// Mirror innerWidth/Height (set by --window-size flag) so the ratio is sane.
|
|
@@ -134,9 +205,15 @@ import{randomInt as hg}from"node:crypto";import{spawn as og}from"node:child_proc
|
|
|
134
205
|
} catch(_) {}
|
|
135
206
|
|
|
136
207
|
// ── screen properties ─────────────────────────────────
|
|
208
|
+
// Headless Chrome often reports an 800x600 screen even when the viewport is
|
|
209
|
+
// 1920x1080. Keep screen metrics internally consistent with our launch flags.
|
|
137
210
|
try {
|
|
138
|
-
|
|
139
|
-
|
|
211
|
+
Object.defineProperty(screen, 'width', { get: () => 1920, configurable: true });
|
|
212
|
+
Object.defineProperty(screen, 'height', { get: () => 1080, configurable: true });
|
|
213
|
+
Object.defineProperty(screen, 'availWidth', { get: () => 1920, configurable: true });
|
|
214
|
+
Object.defineProperty(screen, 'availHeight', { get: () => 1040, configurable: true });
|
|
215
|
+
Object.defineProperty(screen, 'colorDepth', { get: () => 24, configurable: true });
|
|
216
|
+
Object.defineProperty(screen, 'pixelDepth', { get: () => 24, configurable: true });
|
|
140
217
|
} catch(_) {}
|
|
141
218
|
|
|
142
219
|
// ── navigator.userAgentData (UA Client Hints) ─────────
|
|
@@ -209,10 +286,10 @@ import{randomInt as hg}from"node:crypto";import{spawn as og}from"node:child_proc
|
|
|
209
286
|
};
|
|
210
287
|
} catch(_) {}
|
|
211
288
|
})();
|
|
212
|
-
`})])}var
|
|
289
|
+
`})])}var tn={postNav:800,postNavSlow:1200,postClick:300,postType:300,inputPoll:400,copyPoll:600,afterVerify:1500};function q(n){let t=n*0.2,e=tt(-Math.floor(t),Math.floor(t)+1);return Math.max(50,Math.round(n+e))}async function B(n,t,e=15000,o=500){let i=String.raw`
|
|
213
290
|
new Promise((resolve) => {
|
|
214
|
-
const _deadline = Date.now() + ${
|
|
215
|
-
const _baseInterval = ${
|
|
291
|
+
const _deadline = Date.now() + ${e};
|
|
292
|
+
const _baseInterval = ${o};
|
|
216
293
|
|
|
217
294
|
function _jitter(ms) {
|
|
218
295
|
return Math.max(50, ms + (Math.random() * ms * 0.4 - ms * 0.2));
|
|
@@ -220,7 +297,7 @@ import{randomInt as hg}from"node:crypto";import{spawn as og}from"node:child_proc
|
|
|
220
297
|
|
|
221
298
|
function _poll() {
|
|
222
299
|
try {
|
|
223
|
-
if (document.querySelector('${
|
|
300
|
+
if (document.querySelector('${t}')) { resolve(true); return; }
|
|
224
301
|
if (Date.now() < _deadline) { setTimeout(_poll, _jitter(_baseInterval)); }
|
|
225
302
|
else { resolve(false); }
|
|
226
303
|
} catch(_) { resolve(false); }
|
|
@@ -228,27 +305,26 @@ import{randomInt as hg}from"node:crypto";import{spawn as og}from"node:child_proc
|
|
|
228
305
|
|
|
229
306
|
_poll();
|
|
230
307
|
})
|
|
231
|
-
`;return await
|
|
232
|
-
`)}function
|
|
233
|
-
`)}process.stderr.write(`Error: ${
|
|
234
|
-
`),process.exit(1)}import{spawn as
|
|
235
|
-
[greedysearch] Available engines: ${Object.keys(
|
|
236
|
-
`);if(
|
|
237
|
-
`)}}}catch{}return
|
|
238
|
-
`,"utf8")}catch{}}
|
|
239
|
-
[greedysearch] Available synthesizers: ${
|
|
240
|
-
[greedysearch] Falling back to default: ${
|
|
241
|
-
`)}}}catch{}return
|
|
242
|
-
|
|
243
|
-
`}function
|
|
244
|
-
|
|
245
|
-
`)
|
|
246
|
-
`);return
|
|
247
|
-
${
|
|
248
|
-
`)
|
|
249
|
-
`),await
|
|
250
|
-
`)
|
|
251
|
-
`);let W=[Tf({moduleDir:o0,entrypoint:process.argv[1]})];if(process.env.GREEDY_SEARCH_VISIBLE!=="1")W.push("--headless");await new Promise((Q,l)=>{n0(xf(),W,{stdio:["ignore",process.stderr,process.stderr]}).on("close",(N)=>N===0?Q():l(Error("launch.mjs failed")))})}finally{o.release()}}var b0=`
|
|
308
|
+
`;return await f(["eval",n,i],e+5000)==="true"}async function bn(n){let t=n.indexOf("--stdin");if(t===-1)return n;let e=await new Promise((i)=>{let r="";process.stdin.setEncoding("utf8"),process.stdin.on("data",(u)=>r+=u),process.stdin.on("end",()=>i(r.trim()))}),o=[...n];return o[t]=e,o}function mn(n){let t=n.includes("--short"),e=n.filter((l)=>l!=="--short"),o=e.indexOf("--tab"),i=o===-1?null:e[o+1];if(o!==-1)e=e.filter((l,a)=>a!==o&&a!==o+1);let r=e.indexOf("--locale"),u=r===-1?null:e[r+1];if(r!==-1)e=e.filter((l,a)=>a!==r&&a!==r+1);return{query:e.join(" "),tabPrefix:i,short:t,locale:u}}function Wn(n,t){if(!n.length||n[0]==="--help")process.stderr.write(t),process.exit(1)}function jn(n,t,e=300){if(!t||n.length<=e)return n;let o=n.slice(0,e),i=o.lastIndexOf(" ");return i>0?`${o.slice(0,i)}…`:`${o}…`}function Jn(n){process.stdout.write(`${JSON.stringify(n,null,2)}
|
|
309
|
+
`)}function _(n,t,e=null){if(!n||typeof n!=="object")return;let o=e?` (+${Date.now()-e}ms)`:"";if(n.lastStage=t,!Array.isArray(n.stages))n.stages=[];n.stages.push({stage:t,at:Date.now()});let i=n.engine||"extractor";console.error(`[${i}] stage: ${t}${o}`)}function en({engine:n,mode:t="headless",clipboardEmpty:e=null,fallbackUsed:o=null,blockedBy:i=null,verificationResult:r=null,inputReady:u=null,durationMs:l=null,lastStage:a=null,stages:g=null}={}){return{engine:n,mode:t,clipboardEmpty:e,fallbackUsed:o,blockedBy:i,verificationResult:r,inputReady:u,durationMs:l,lastStage:a,stages:g}}function xn(n,t=null){if(t){let e=JSON.stringify({_envelope:t,error:n.message});process.stdout.write(`${e}
|
|
310
|
+
`)}process.stderr.write(`Error: ${n.message}
|
|
311
|
+
`),process.exit(1)}import{spawn as Ut,execFileSync as gn,execSync as Te}from"node:child_process";import{basename as st}from"node:path";function Nn(n=process.env,t=process.execPath){let e=n.GREEDY_SEARCH_NODE||n.NODE_BINARY||n.NODE;if(e?.trim())return e.trim();let o=st(t||"").toLowerCase();if(o==="node"||o==="node.exe")return t;return"node"}import{existsSync as Cn,readFileSync as hn,renameSync as Mt,unlinkSync as $,writeFileSync as I}from"node:fs";import sn from"node:http";import{platform as Gn}from"node:os";import{join as At}from"node:path";import{existsSync as Zn}from"node:fs";import{platform as ct}from"node:os";import{join as j}from"node:path";function w(n){let t=ct()==="win32",e=process.env.SystemRoot||"C:\\Windows",o={win32:{powershell:j(e,"System32","WindowsPowerShell","v1.0","powershell.exe"),powershell_ise:j(e,"System32","WindowsPowerShell","v1.0","powershell_ise.exe"),netstat:j(e,"System32","netstat.exe"),taskkill:j(e,"System32","taskkill.exe"),tasklist:j(e,"System32","tasklist.exe"),cmd:j(e,"System32","cmd.exe")},unix:{ps:"/usr/bin/ps",lsof:"/usr/bin/lsof",ss:"/usr/sbin/ss",grep:"/usr/bin/grep",kill:"/usr/bin/kill"}},i=t?o.win32:o.unix,r=n.toLowerCase();if(i[r]&&Zn(i[r]))return i[r];if(t&&r==="netstat"){let u=j(e,"Sysnative","netstat.exe");if(Zn(u))return u}return n}import{execFileSync as wt}from"node:child_process";import{platform as pt}from"node:os";function yt(n,t){return wt(w(n),t,{encoding:"utf8",stdio:["ignore","pipe","ignore"],timeout:5000})}function _t(n){let t=String(n||"").match(/\b(\d+)\b/);return t?Number.parseInt(t[1],10):null}function vt(n){return _t(n)}function $t(n,t){for(let e of String(n||"").split(/\r?\n/)){if(!/\bLISTEN\b/i.test(e))continue;if(!e.trim().split(/\s+/).slice(0,6).some((r)=>r.endsWith(`:${t}`)))continue;let i=e.match(/\bpid=(\d+)\b/);if(i)return Number.parseInt(i[1],10)}return null}function bt(n,t){for(let e of String(n||"").split(/\r?\n/)){let o=e.trim().split(/\s+/);if(o.length<5||o[0].toUpperCase()!=="TCP")continue;if(!o.at(-2)?.toUpperCase().startsWith("LISTEN"))continue;if(!o[1].endsWith(`:${t}`))continue;let i=Number.parseInt(o.at(-1),10);if(Number.isInteger(i)&&i>0)return i}return null}function rn(n,t,e){try{return n(t,e)}catch{return null}}function Xn(n,{platformName:t=pt(),run:e=yt}={}){if(t==="win32")return bt(rn(e,"netstat",["-ano","-p","TCP"]),n);let o=rn(e,"lsof",["-nP",`-iTCP:${n}`,"-sTCP:LISTEN","-t"]),i=vt(o);if(i)return i;if(t!=="linux")return null;return $t(rn(e,"ss",["-ltnp"]),n)}import{existsSync as T,mkdirSync as mt,readFileSync as Bn,writeFileSync as Wt}from"node:fs";import{homedir as jt}from"node:os";import{join as Qn}from"node:path";import{tmpdir as Jt}from"node:os";function xt(n,t=9222){let e=Number.parseInt(String(n??""),10);return Number.isInteger(e)&&e>1024&&e<65535?e:t}var Nt=Jt().replaceAll("\\","/"),s=xt(process.env.GREEDY_SEARCH_PORT),c=(process.env.GREEDY_SEARCH_PROFILE_DIR||process.env.CDP_PROFILE_DIR||`${Nt}/greedysearch-chrome-profile`).replaceAll("\\","/"),Q=`${c}/DevToolsActivePort`,P=process.env.GREEDY_SEARCH_PID_FILE||`${c}/browser.pid`,Zt=process.env.CDP_PAGES_CACHE||`${c}/cdp-pages.json`,W=process.env.GREEDY_SEARCH_MODE_FILE||`${c}/browser-mode`,kn=process.env.GREEDY_SEARCH_METADATA_FILE||`${c}/browser-metadata.json`,Vn=process.env.GREEDY_SEARCH_LAUNCH_LOCK_FILE||`${c}/browser-launch.lock`,K=process.env.GREEDY_SEARCH_ACTIVITY_FILE||`${c}/browser-last-activity`,Ze=(process.env.CDP_SOCKET_DIR||`${c}/cdp-sockets`).replaceAll("\\","/"),Xe=`${c}/visible-recovery.jsonl`,un=Qn(jt(),".dm"),v=Qn(un,"greedyconfig"),ln=["perplexity","google","chatgpt","gemini"],fn="gemini";function Xt(){try{if(T(v)){let n=Bn(v,"utf8"),t=JSON.parse(n);if(Array.isArray(t.engines)&&t.engines.length>0&&t.engines.every((e)=>typeof e==="string")){let e=t.engines.filter((i)=>on[i]),o=t.engines.filter((i)=>!on[i]);if(o.length>0)process.stderr.write(`[greedysearch] Warning: ignoring unknown engine(s) in ${v}: ${o.join(", ")}
|
|
312
|
+
[greedysearch] Available engines: ${Object.keys(on).join(", ")}
|
|
313
|
+
`);if(e.length>0)return e;process.stderr.write(`[greedysearch] Warning: no valid engines in ${v}, falling back to defaults: ${ln.join(", ")}
|
|
314
|
+
`)}}}catch{}return ln}function qt(){try{if(!T(un))mt(un,{recursive:!0});if(!T(v))Wt(v,JSON.stringify({engines:ln,synthesizer:fn},null,2)+`
|
|
315
|
+
`,"utf8")}catch{}}qt();var qn=["gemini","chatgpt"];function Bt(){try{if(T(v)){let n=Bn(v,"utf8"),t=JSON.parse(n);if(typeof t.synthesizer==="string"){let e=t.synthesizer.toLowerCase();if(qn.includes(e))return e;process.stderr.write(`[greedysearch] Warning: unknown synthesizer "${t.synthesizer}" in ${v}
|
|
316
|
+
[greedysearch] Available synthesizers: ${qn.join(", ")}
|
|
317
|
+
[greedysearch] Falling back to default: ${fn}
|
|
318
|
+
`)}}}catch{}return fn}var on={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"},qe=Xt();var Be=Bt(),Qe=Math.max(1,Number.parseInt(process.env.GREEDY_FETCH_CONCURRENCY||"5",10)||5);process.env.CDP_PROFILE_DIR=c;import{execFileSync as Hn,execSync as zn}from"node:child_process";import{existsSync as Y,mkdirSync as Qt,readFileSync as X,unlinkSync as x,writeFileSync as N}from"node:fs";import{platform as On}from"node:os";var C=kn,J=Vn,kt=15000,G=P,S=W,k=K;function V(n){if(!Number.isInteger(n)||n<=0)return!1;try{return process.kill(n,0),!0}catch{return!1}}function Vt(n){if(!V(n))return null;try{if(On()==="win32")return Hn(w("powershell"),["-NoProfile","-NonInteractive","-Command",`(Get-CimInstance Win32_Process -Filter "ProcessId = ${n}").CommandLine`],{encoding:"utf8",windowsHide:!0,timeout:5000}).trim()||null;return Hn(w("ps"),["-p",String(n),"-o","command="],{encoding:"utf8",timeout:5000}).trim()||null}catch{return null}}function Ht(n,t,e=s){if(!n)return!1;let o=(u)=>String(u||"").replaceAll("\\","/").toLowerCase(),i=o(n),r=o(t);return i.includes(r)&&i.includes(`--remote-debugging-port=${e}`)&&!i.includes("--type=")}function Un(n,t,e=s){return Ht(Vt(n),t,e)}function zt(n=s){try{if(On()==="win32"){let e=zn(`${w("netstat")} -ano -p TCP 2>nul`,{encoding:"utf8"}),o=new RegExp(String.raw`TCP\s+\S+:${n}\s+\S+:0\s+LISTENING\s+(\d+)`,"i"),i=e.match(o);return i?Number.parseInt(i[1],10):null}let t=zn(`${w("lsof")} -i :${n} -t 2>/dev/null || ${w("ss")} -tlnp 2>/dev/null | ${w("grep")} :${n} | ${w("grep")} -oP 'pid=\\K\\d+'`,{encoding:"utf8"}).trim();return t?Number.parseInt(t.split(`
|
|
319
|
+
`)[0],10):null}catch{return null}}function H(){try{if(Y(C)){let n=X(C,"utf8"),t=JSON.parse(n);if(t&&typeof t.tempDir==="string"&&typeof t.debugPort==="number")return{browserPid:Number.isInteger(t.browserPid)?t.browserPid:void 0,debugPort:t.debugPort,tempDir:t.tempDir,clientPids:Array.isArray(t.clientPids)?t.clientPids.filter((e)=>Number.isInteger(e)&&e>0):[],sessionMode:t.sessionMode==="visible"?"visible":"headless",lastActivity:Number.isFinite(t.lastActivity)?t.lastActivity:0,launchedAt:Number.isFinite(t.launchedAt)?t.launchedAt:0}}}catch{}try{let n=Y(G)?Number.parseInt(X(G,"utf8").trim(),10)||void 0:void 0,t=Y(S)?X(S,"utf8").trim()==="visible"?"visible":"headless":"headless",e=Y(k)?Number.parseInt(X(k,"utf8").trim(),10)||0:0;return{browserPid:n,debugPort:s,tempDir:c,clientPids:n?[n]:[],sessionMode:t,lastActivity:e,launchedAt:0}}catch{return null}}function L(n){try{N(C,JSON.stringify({browserPid:n.browserPid,debugPort:n.debugPort,tempDir:n.tempDir,clientPids:[...new Set(n.clientPids.filter((t)=>t>0))],sessionMode:n.sessionMode,lastActivity:n.lastActivity,launchedAt:n.launchedAt},null,2),"utf8")}catch{}try{if(n.browserPid)N(G,String(n.browserPid),"utf8")}catch{}try{N(S,n.sessionMode,"utf8")}catch{}try{N(k,String(n.lastActivity),"utf8")}catch{}}function Mn(){try{x(C)}catch{}try{x(G)}catch{}try{x(S)}catch{}try{x(k)}catch{}}function an(n){if(!n)return n;let t={...n,clientPids:[...new Set([...n.clientPids,process.pid].filter((e)=>V(e)||e===process.pid))]};return L(t),t}function F(n){let t=Date.now();try{if(n)L({...n,lastActivity:t});else N(k,String(t),"utf8")}catch{}}var Ae=Number.parseInt(process.env.GREEDY_SEARCH_IDLE_TIMEOUT_MINUTES||"5",10)||5;var An=!1;function Dn(){if(process.env.GREEDY_SEARCH_RESEARCH_CHILD)return;if(An)return;An=!0;let n=H();if(!n)return;if(n.browserPid){if(!V(n.browserPid)){Mn();return}if(!Un(n.browserPid,n.tempDir,n.debugPort))Mn();else L({...n,clientPids:n.clientPids.filter((i)=>V(i))})}let t=zt();if(t&&t!==n.browserPid)if(Un(t,c,s))L({browserPid:t,debugPort:s,tempDir:c,clientPids:[t],sessionMode:n.sessionMode,lastActivity:Date.now(),launchedAt:Date.now()});else process.stderr.write(`[greedysearch] Refusing to kill unverified listener ${t} on port ${s}.
|
|
320
|
+
`)}function Tn(){Qt(c,{recursive:!0});try{let n=JSON.stringify({pid:process.pid,ts:Date.now()});return N(J,n,{encoding:"utf8",flag:"wx"}),{acquired:!0,release:()=>{try{let t=X(J,"utf8");if(JSON.parse(t).pid===process.pid)x(J)}catch{}}}}catch(n){if(n?.code!=="EEXIST")return{acquired:!1,release:()=>{}}}try{let n=X(J,"utf8"),t=JSON.parse(n),e=Date.now()-(t.ts||0);if(!V(t.pid)||e>kt){try{x(J)}catch{}try{let i=JSON.stringify({pid:process.pid,ts:Date.now()});return N(J,i,{encoding:"utf8",flag:"wx"}),{acquired:!0,release:()=>{try{x(J)}catch{}}}}catch{return{acquired:!1,release:()=>{}}}}}catch{}return{acquired:!1,release:()=>{}}}var Ot=import.meta.dirname||new URL(".",import.meta.url).pathname.replace(/^\/([A-Z]:)/,"$1"),Pn=P,z=K,Dt=Number.parseInt(process.env.GREEDY_SEARCH_IDLE_TIMEOUT_MINUTES||"5",10)||5,Tt=Number.parseInt(process.env.GREEDY_SEARCH_VISIBLE_IDLE_TIMEOUT_MINUTES||"60",10)||60;function Pt(n,t=s){let e=String(n||"").toLowerCase();if(!e.includes(`--remote-debugging-port=${t}`)||e.includes("--type="))return null;return e.includes("--headless")}function Sn(){try{let n=E(),t=n?Ln(n):null,e=Pt(t);if(e!==null){try{I(W,e?"headless":"visible","utf8")}catch{}return e}}catch{}try{if(!Cn(W))return!0;return hn(W,"utf8").trim()==="headless"}catch{return!0}}function Kt(){try{I(z,String(Date.now()),"utf8")}catch{}try{let n=H();if(n)F(n)}catch{}}function Ln(n){try{if(Gn()==="win32")return gn(w("powershell"),["-NoProfile","-NonInteractive","-Command",`(Get-CimInstance Win32_Process -Filter "ProcessId = ${n}").CommandLine`],{encoding:"utf8",windowsHide:!0,timeout:5000}).trim()||null;return gn(w("ps"),["-p",String(n),"-o","command="],{encoding:"utf8",timeout:5000}).trim()||null}catch{return null}}function Yt(n){let t=String(n||"").replaceAll("\\","/"),e=c.replaceAll("\\","/");return t.includes(`--remote-debugging-port=${s}`)&&t.includes(`--user-data-dir=${e}`)&&!t.includes("--type=")}function E(){return Xn(s)}function d(){let n=E();return n&&Yt(Ln(n))?n:null}async function Ct(n=1500){let t=d();if(!t)return process.stderr.write(`[greedysearch] Refusing to close an unverified listener.
|
|
321
|
+
`),!1;try{let o=await new Promise((r,u)=>{let l=sn.get(`http://localhost:${s}/json/version`,(a)=>{let g="";a.on("data",(h)=>g+=h),a.on("end",()=>{try{r(JSON.parse(g))}catch{u(Error("bad JSON"))}})});l.on("error",u),l.setTimeout(1000,()=>{l.destroy(),u(Error("timeout"))})}),i=new globalThis.WebSocket(o.webSocketDebuggerUrl);await new Promise((r)=>{i.onopen=()=>{if(d()!==t){i.close(),r();return}i.send(JSON.stringify({id:1,method:"Browser.close"})),setTimeout(()=>{i.close(),r()},200)},i.onerror=()=>r(),setTimeout(r,1000)})}catch{}let e=Date.now()+n;while(Date.now()<e){let o=E();if(!o)return!0;if(o!==t)return!1;await new Promise((i)=>setTimeout(i,150))}return Gt(t)}function Gt(n=null){try{let t=d();if(!t||n&&t!==n)return!1;if(Gn()==="win32")gn(w("taskkill"),["/F","/PID",String(t)],{stdio:"ignore",windowsHide:!0});else process.kill(t,"SIGKILL");return!0}catch{return!1}}async function Fn(){if(!d()){if(E())process.stderr.write(`[greedysearch] Refusing to kill an unverified listener.
|
|
322
|
+
`);return!1}if(!await b(500)){try{$(Pn)}catch{}try{$(z)}catch{}try{$(W)}catch{}return!1}let t=await Ct(1500);try{$(Pn)}catch{}try{$(z)}catch{}try{$(W)}catch{}if(t)process.stderr.write(`[greedysearch] Killed Chrome on port ${s}.
|
|
323
|
+
`);return t}var Kn=Fn;async function St(){let t=Sn()?Dt:Tt;if(t<=0)return!1;if(!Cn(z))return Kt(),!1;try{let e=Number.parseInt(hn(z,"utf8").trim(),10);if(!e)return!1;if((Date.now()-e)/60000>=t)return Fn()}catch{}return!1}function b(n=3000){return new Promise((t)=>{let e=sn.get(`http://localhost:${s}/json/version`,(o)=>{o.resume(),t(o.statusCode===200)});e.on("error",()=>t(!1)),e.setTimeout(n,()=>{e.destroy(),t(!1)})})}async function Yn(n=3000,t=200){let e=Date.now()+n;while(Date.now()<e){if(!await b(300))return!0;await new Promise((o)=>setTimeout(o,t))}return!await b(300)}async function R(){let n=`${Q}.lock`,t=`${Q}.tmp`,e=5000,o=1000,i=await new Promise((r)=>{let u=Date.now(),l=()=>{try{let a=JSON.stringify({pid:process.pid,ts:Date.now()});I(n,a,{encoding:"utf8",flag:"wx"}),r(!0)}catch(a){if(a?.code!=="EEXIST"){if(Date.now()-u<1000)setTimeout(l,50);else r(!1);return}try{let g=hn(n,"utf8").trim(),h=g.startsWith("{")?JSON.parse(g):{ts:Number(g)},m=Number(h?.ts)||0;if(m>0&&Date.now()-m>5000)try{$(n)}catch{}if(Date.now()-u<1000)setTimeout(l,50);else r(!1)}catch{if(Date.now()-u<1000)setTimeout(l,50);else r(!1)}}};l()});try{let r=await new Promise((a,g)=>{let h=sn.get(`http://localhost:${s}/json/version`,(m)=>{let U="";m.on("data",(M)=>U+=M),m.on("end",()=>a(U))});h.on("error",g),h.setTimeout(3000,()=>{h.destroy(),g(Error("timeout"))})}),{webSocketDebuggerUrl:u}=JSON.parse(r),l=new URL(u).pathname;if(i){I(t,`${s}
|
|
324
|
+
${l}`,"utf8");try{$(Q)}catch{}Mt(t,Q)}}catch{}finally{if(i)try{$(n)}catch{}}}async function Rn(){if(process.env.GREEDY_SEARCH_RESEARCH_CHILD&&await b()){await R();try{let r=H();if(r)F(r),an(r)}catch{}return}Dn();let n=await St(),t=n?!1:await b();if(!t&&!n)await new Promise((r)=>setTimeout(r,500)),t=await b();let e=!1;if(t){let r=Sn(),u=process.env.GREEDY_SEARCH_VISIBLE==="1";if(!u&&!r)process.stderr.write(`[greedysearch] Visible Chrome detected — switching to headless mode...
|
|
325
|
+
`),await Kn(),await Yn(),e=!0;else if(u&&r)process.stderr.write(`[greedysearch] Headless Chrome detected — switching to visible mode...
|
|
326
|
+
`),await Kn(),await Yn(),e=!0}if(e?!1:await b()){await R();try{let r=H();if(r)F(r),an(r)}catch{}return}let i=Tn();if(!i.acquired){let r=Date.now()+12000,u=!1;while(Date.now()<r){if(u=await b(500),u)break;await new Promise((l)=>setTimeout(l,250))}if(u){await R();return}}try{if(await b(1000)){await R();return}process.stderr.write(`GreedySearch Chrome not running on port ${s} — auto-launching...
|
|
327
|
+
`);let u=[At(Ot,"..","..","bin","launch.mjs")];if(process.env.GREEDY_SEARCH_VISIBLE!=="1")u.push("--headless");await new Promise((l,a)=>{Ut(Nn(),u,{stdio:["ignore",process.stderr,process.stderr]}).on("close",(h)=>h===0?l():a(Error("launch.mjs failed")))})}finally{i.release()}}var Lt=`
|
|
252
328
|
(function() {
|
|
253
329
|
// Google consent page (consent.google.com)
|
|
254
330
|
var g = document.querySelector('#L2AGLb, button[jsname="b3VHJd"], .tHlp8d');
|
|
@@ -265,10 +341,10 @@ ${W}`,"utf8");try{V(O)}catch{}w0(g,O)}}catch{}finally{if($)try{V(f)}catch{}}}asy
|
|
|
265
341
|
|
|
266
342
|
return null;
|
|
267
343
|
})()
|
|
268
|
-
`;async function
|
|
344
|
+
`;async function cn(n,t){let e=await t(["eval",n,Lt]).catch(()=>null);if(e&&e!=="null")await new Promise((o)=>setTimeout(o,1500))}var y={input:'textarea[name="newMessage"]',submitButton:'button[aria-label="Submit search"]',answerContainer:'div[class*="prose"]',paperCard:'a[data-testid="search-result"]',exportButton:'button[aria-label="Export"]'};async function Ft(n){return await f(["eval",n,`(() => {
|
|
269
345
|
const url = document.location.href || '';
|
|
270
346
|
return url.indexOf('/sign-up/') !== -1 || url.indexOf('redirect_url=') !== -1;
|
|
271
|
-
})()`]).catch(()=>"false")==="true"}async function
|
|
347
|
+
})()`]).catch(()=>"false")==="true"}async function In(n){try{return JSON.parse(await f(["eval",n,`(() => {
|
|
272
348
|
const url = document.location.href || '';
|
|
273
349
|
const title = document.title || '';
|
|
274
350
|
const text = document.body?.innerText || '';
|
|
@@ -279,7 +355,14 @@ ${W}`,"utf8");try{V(O)}catch{}w0(g,O)}}catch{}finally{if($)try{V(f)}catch{}}}asy
|
|
|
279
355
|
text.includes('refresh_request_origin_azp_mismatch') ||
|
|
280
356
|
(text.includes('HTTP ERROR 405') && text.includes('This page isn'));
|
|
281
357
|
return JSON.stringify({ stale, url, title, text: text.slice(0, 500) });
|
|
282
|
-
})()`],5000))}catch{return{stale:!1,url:"",title:"",text:""}}}async function
|
|
358
|
+
})()`],5000))}catch{return{stale:!1,url:"",title:"",text:""}}}async function Rt(n){for(let t of["https://consensus.app","https://clerk.consensus.app"])await f(["evalraw",n,"Storage.clearDataForOrigin",JSON.stringify({origin:t,storageTypes:"all"})]).catch((e)=>{console.error(`[consensus] Warning: failed to clear stale auth storage for ${t}: ${e.message}`)})}async function dn(n,t,e){let o=await In(n);if(!o.stale)return!1;if(_(t,"auth-storage-reset",e),console.error(`[consensus] Detected stale Clerk/Consensus auth state (${o.title||o.url}) — clearing per-origin storage and retrying navigation`),t.fallbackUsed="clear-stale-consensus-auth",await Rt(n),await f(["nav",n,"https://consensus.app/"],20000),await new Promise((r)=>setTimeout(r,900)),(await In(n)).stale)throw t.blockedBy="signin",t.verificationResult="needs-human",Error("Consensus auth session is stale — visible Chrome is open. Please sign in again, then rerun the search.");return!0}async function It(n,t){await f(["click",n,y.input]),await new Promise((u)=>setTimeout(u,q(200)));let e=async()=>{await nn(["type",n,"--stdin"],t),await new Promise((u)=>setTimeout(u,q(300)))},o=async()=>{let u=await f(["eval",n,`JSON.stringify(document.querySelector('${y.input}')?.value || '')`]);try{return JSON.parse(u)}catch{return u}},i=async()=>_n(await o(),t),r=async()=>{await f(["eval",n,`(() => {
|
|
359
|
+
const el = document.querySelector('${y.input}');
|
|
360
|
+
if (!el) return false;
|
|
361
|
+
el.focus();
|
|
362
|
+
el.select();
|
|
363
|
+
document.execCommand('delete');
|
|
364
|
+
return true;
|
|
365
|
+
})()`])};if(await e(),await i())return;if(await r(),await e(),!await i())throw Error("Consensus input did not accept text — input verification failed")}async function dt(n){let e=await f(["eval",n,`(() => {
|
|
283
366
|
if (window.__pdiInstalled) return 'already';
|
|
284
367
|
window.__pdiInstalled = true;
|
|
285
368
|
const _origOpen = XMLHttpRequest.prototype.open;
|
|
@@ -294,14 +377,22 @@ ${W}`,"utf8");try{V(O)}catch{}w0(g,O)}}catch{}finally{if($)try{V(f)}catch{}}}asy
|
|
|
294
377
|
if (this.status === 200) {
|
|
295
378
|
try {
|
|
296
379
|
const parsed = JSON.parse(this.responseText);
|
|
297
|
-
//
|
|
298
|
-
//
|
|
299
|
-
|
|
300
|
-
|
|
380
|
+
// Keep only {largest, latest} instead of every
|
|
381
|
+
// partial Load-More response, to bound page
|
|
382
|
+
// memory. "latest" lets the caller detect the
|
|
383
|
+
// .CSV response fired after clickExportCsv;
|
|
384
|
+
// "largest" is the timeout fallback.
|
|
385
|
+
const entry = {
|
|
301
386
|
at: Date.now(),
|
|
302
387
|
count: Object.keys(parsed?.paperDetailsListByPaperId || {}).length,
|
|
303
388
|
data: parsed,
|
|
304
|
-
}
|
|
389
|
+
};
|
|
390
|
+
const store = window.__papersDetailsResps ||
|
|
391
|
+
(window.__papersDetailsResps = { largest: null, latest: null });
|
|
392
|
+
store.latest = entry;
|
|
393
|
+
if (!store.largest || entry.count > store.largest.count) {
|
|
394
|
+
store.largest = entry;
|
|
395
|
+
}
|
|
305
396
|
} catch (e) {
|
|
306
397
|
window.__papersDetailsErrors = window.__papersDetailsErrors || [];
|
|
307
398
|
window.__papersDetailsErrors.push(String(e.message || e));
|
|
@@ -312,50 +403,92 @@ ${W}`,"utf8");try{V(O)}catch{}w0(g,O)}}catch{}finally{if($)try{V(f)}catch{}}}asy
|
|
|
312
403
|
return _origSend.apply(this, arguments);
|
|
313
404
|
};
|
|
314
405
|
return 'installed';
|
|
315
|
-
})()`]);return
|
|
316
|
-
const _deadline = Date.now() + ${
|
|
406
|
+
})()`]);return e==="installed"||e==="already"}async function Et(n,t=1e4,e=0){let o=`new Promise((resolve) => {
|
|
407
|
+
const _deadline = Date.now() + ${t};
|
|
408
|
+
const _after = ${e};
|
|
317
409
|
function _check() {
|
|
318
|
-
const
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
resolve(JSON.stringify({ ok: true, count:
|
|
410
|
+
const store = window.__papersDetailsResps;
|
|
411
|
+
const latest = store && store.latest;
|
|
412
|
+
if (latest && latest.at > _after) {
|
|
413
|
+
resolve(JSON.stringify({ ok: true, count: latest.count, data: latest.data }));
|
|
322
414
|
return;
|
|
323
415
|
}
|
|
324
416
|
if (Date.now() < _deadline) {
|
|
325
417
|
setTimeout(_check, 200);
|
|
326
418
|
} else {
|
|
327
|
-
|
|
419
|
+
const largest = store && store.largest;
|
|
420
|
+
if (largest) {
|
|
421
|
+
resolve(JSON.stringify({ ok: true, count: largest.count, data: largest.data, stale: true }));
|
|
422
|
+
} else {
|
|
423
|
+
resolve(JSON.stringify({ ok: false, reason: 'timeout' }));
|
|
424
|
+
}
|
|
328
425
|
}
|
|
329
426
|
}
|
|
330
427
|
_check();
|
|
331
|
-
})`,
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
const
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
428
|
+
})`,i=await f(["eval",n,o],t+5000);try{return JSON.parse(i)}catch{return{ok:!1,reason:"invalid-json"}}}async function ne(n,t=8){if(!await B(n,y.paperCard,20000,500).catch(()=>!1))return console.error("[consensus] Warning: no paper cards appeared within 20s — Load More will be skipped"),0;let o=String.raw`
|
|
429
|
+
new Promise((resolve) => {
|
|
430
|
+
const _paperSel = '${y.paperCard}';
|
|
431
|
+
const _maxClicks = ${t};
|
|
432
|
+
function _findLoadMore() {
|
|
433
|
+
const btns = Array.from(document.querySelectorAll('button'));
|
|
434
|
+
return btns.find(b => {
|
|
435
|
+
const t = (b.innerText || '').trim();
|
|
436
|
+
return /load more/i.test(t) || /more results/i.test(t) || /show more/i.test(t);
|
|
437
|
+
}) || null;
|
|
438
|
+
}
|
|
439
|
+
function _cardCount() { return document.querySelectorAll(_paperSel).length; }
|
|
440
|
+
let _clicks = 0;
|
|
441
|
+
function _waitButton(deadline, cb) {
|
|
442
|
+
const btn = _findLoadMore();
|
|
443
|
+
if (btn) { cb(btn); return; }
|
|
444
|
+
if (Date.now() < deadline) { setTimeout(() => _waitButton(deadline, cb), 200); }
|
|
445
|
+
else { cb(null); }
|
|
446
|
+
}
|
|
447
|
+
function _loop() {
|
|
448
|
+
if (_clicks >= _maxClicks) { resolve(JSON.stringify({ clicks: _clicks, cards: _cardCount() })); return; }
|
|
449
|
+
const mountDeadline = Date.now() + (_clicks === 0 ? 3000 : 500);
|
|
450
|
+
_waitButton(mountDeadline, (btn) => {
|
|
451
|
+
if (!btn || btn.disabled) { resolve(JSON.stringify({ clicks: _clicks, cards: _cardCount() })); return; }
|
|
452
|
+
const before = _cardCount();
|
|
453
|
+
btn.click();
|
|
454
|
+
_clicks++;
|
|
455
|
+
const clickDeadline = Date.now() + 4000;
|
|
456
|
+
(function _pollCards() {
|
|
457
|
+
if (_cardCount() > before || Date.now() >= clickDeadline) { _loop(); return; }
|
|
458
|
+
setTimeout(_pollCards, 200);
|
|
459
|
+
})();
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
_loop();
|
|
463
|
+
})
|
|
464
|
+
`,i=await f(["eval",n,o],t*5000+5000).catch(()=>null);if(!i)return 0;try{let{clicks:r,cards:u}=JSON.parse(i);return console.error(`[consensus] expandReferences: ${r} click(s), ${u} card(s)`),r}catch{return 0}}async function te(n,t=1200){let e=String.raw`
|
|
465
|
+
new Promise((resolve) => {
|
|
466
|
+
const _sel = '${y.paperCard}';
|
|
467
|
+
const _deadline = Date.now() + ${t};
|
|
468
|
+
let _last = document.querySelectorAll(_sel).length;
|
|
469
|
+
function _poll() {
|
|
470
|
+
const cur = document.querySelectorAll(_sel).length;
|
|
471
|
+
if (cur === _last) { resolve(cur); return; }
|
|
472
|
+
_last = cur;
|
|
473
|
+
if (Date.now() < _deadline) { setTimeout(_poll, 300); }
|
|
474
|
+
else { resolve(_last); }
|
|
475
|
+
}
|
|
476
|
+
setTimeout(_poll, 300);
|
|
477
|
+
})
|
|
478
|
+
`;await f(["eval",n,e],t+3000).catch(()=>null)}async function ee(n){return await f(["eval",n,`(() => {
|
|
479
|
+
const btn = document.querySelector('${y.exportButton}');
|
|
347
480
|
if (!btn) return 'no-export';
|
|
348
481
|
btn.scrollIntoView({ block: 'center' });
|
|
349
482
|
btn.click();
|
|
350
483
|
return 'opened';
|
|
351
|
-
})()`]),await new Promise((
|
|
484
|
+
})()`]),await new Promise((e)=>setTimeout(e,600)),await f(["eval",n,`(() => {
|
|
352
485
|
const btn = Array.from(document.querySelectorAll('button'))
|
|
353
486
|
.find(b => /\\.CSV/.test((b.innerText || '').trim()));
|
|
354
487
|
if (!btn) return 'no-csv';
|
|
355
488
|
btn.click();
|
|
356
489
|
return 'clicked';
|
|
357
|
-
})()`])}function
|
|
358
|
-
const cards = Array.from(document.querySelectorAll('${
|
|
490
|
+
})()`])}function ie(n){let t=n?.paperDetailsListByPaperId||{},e=Object.keys(t),o=[];for(let i=0;i<e.length;i++){let r=t[e[i]]||{},u=r.url_slug||"",l=r.paper_id||r.hash_paper_id||e[i],a;if(u)a=`https://consensus.app/papers/${u}/${l}/`;else if(r.provider_url)a=r.provider_url;else if(r.doi)a=`https://doi.org/${r.doi}`;else a=`https://consensus.app/paper/${l}`;let g=[],h=r.badges||{};if(h.study_type==="rct")g.push("RCT");else if(h.study_type==="meta_analysis")g.push("META-ANALYSIS");else if(h.study_type==="systematic_review")g.push("SYSTEMATIC REVIEW");else if(h.study_type)g.push(h.study_type.toUpperCase());if(h.rigorous_journal)g.push("RIGOROUS JOURNAL");if(h.very_rigorous_journal)g.push("VERY RIGOROUS JOURNAL");if(h.highly_cited_paper)g.push("HIGHLY CITED");if(h.large_human_trial)g.push("LARGE HUMAN TRIAL");if(r.is_retracted)g.push("RETRACTED");if(r.open_access_pdf_url)g.push("OPEN ACCESS");o.push({title:r.title||"",url:a,rank:i+1,authors:Array.isArray(r.authors)?r.authors:[],year:r.year||null,journal:r.journal||r.publisher_name||null,doi:r.doi||null,citation_count:r.citation_count||0,snippet:r.abstract_takeaway||"",tags:g})}return o}async function En(n){let t=`(() => {
|
|
491
|
+
const cards = Array.from(document.querySelectorAll('${y.paperCard}'));
|
|
359
492
|
const sources = [];
|
|
360
493
|
const seen = new Set();
|
|
361
494
|
for (const card of cards) {
|
|
@@ -377,8 +510,8 @@ ${W}`,"utf8");try{V(O)}catch{}w0(g,O)}}catch{}finally{if($)try{V(f)}catch{}}}asy
|
|
|
377
510
|
sources.push({ title, url, rank, snippet, tags });
|
|
378
511
|
}
|
|
379
512
|
return JSON.stringify(sources);
|
|
380
|
-
})()`,
|
|
381
|
-
const prose = document.querySelector('${
|
|
513
|
+
})()`,e=await f(["eval",n,t],1e4);try{return JSON.parse(e)}catch{return[]}}async function re(n){let t=`(() => {
|
|
514
|
+
const prose = document.querySelector('${y.answerContainer}');
|
|
382
515
|
return prose?.innerText?.trim() || '';
|
|
383
|
-
})()`;return await
|
|
384
|
-
`;async function
|
|
516
|
+
})()`;return await f(["eval",n,t],1e4)||""}var oe=`Usage: node extractors/consensus.mjs "<query>" [--tab <prefix>]
|
|
517
|
+
`;async function ue(){let n=await bn(process.argv.slice(2));Wn(n,oe);let{query:t,tabPrefix:e,short:o}=mn(n),i=Date.now(),u={engine:"consensus",mode:process.env.GREEDY_SEARCH_VISIBLE==="1"?"visible":"headless",clipboardEmpty:null,fallbackUsed:null,blockedBy:null,verificationResult:null,inputReady:null};try{if(process.env.GREEDY_SEARCH_VISIBLE!=="1"&&process.env.GREEDY_SEARCH_ALWAYS_VISIBLE!=="1")process.env.GREEDY_SEARCH_HEADLESS="1";if(await Rn(),!e)await f(["list"]);let l=await vn(e),a=await f(["eval",l,"document.location.href"]).catch(()=>""),g=!1;try{let p=new URL(a).hostname.toLowerCase();g=p==="consensus.app"||p.endsWith(".consensus.app")}catch{}if(!g)_(u,"nav",i),await f(["nav",l,"https://consensus.app/"],20000),await new Promise((p)=>setTimeout(p,600));await dn(l,u,i),await cn(l,f),_(u,"input-wait",i);let h=await B(l,y.input,15000,400);if(u.inputReady=h,!h)if(await dn(l,u,i)){let O=await B(l,y.input,15000,400);if(u.inputReady=O,O)await cn(l,f);else throw Error("Consensus input not found after stale auth recovery — page may not have loaded or is in unexpected state")}else throw Error("Consensus input not found — page may not have loaded or is in unexpected state");if(await new Promise((p)=>setTimeout(p,q(tn.postClick))),_(u,"type-and-submit",i),await It(l,t),await new Promise((p)=>setTimeout(p,q(tn.postType))),await f(["eval",l,`document.querySelector('${y.submitButton}')?.click()`]),await new Promise((p)=>setTimeout(p,2000)),await Ft(l))throw u.blockedBy="signin",Error("Consensus requires sign-in — please sign in or create a free account in the visible browser window. Once signed in, cookies persist for future runs.");_(u,"answer-wait",i),await B(l,y.answerContainer,30000,500),await dt(l),_(u,"expand-refs",i);let m=await ne(l,8);if(m===0)console.error("[consensus] Note: 'Load more results' button not present (initial page has all references)");else console.error(`[consensus] Clicked 'Load more results' ${m} time(s) to expand references`);await te(l,1200),_(u,"csv-click",i);let U=Number(await f(["eval",l,"Date.now()"]).catch(()=>"0")||0),M=await ee(l);if(M!=="clicked")console.error(`[consensus] Export → .CSV click did not register (${M}) — falling back to DOM`);_(u,"wait-csv-resp",i);let A=await Et(l,12000,U),Z=[],wn="dom";if(A.ok)Z=ie(A.data),wn="api-intercept",console.error(`[consensus] Captured /api/papers/details/ response with ${A.count} paper(s)`);else console.error(`[consensus] /api/papers/details/ response not captured (${A.reason}) — falling back to DOM cards`);_(u,"extract",i);let pn=await re(l);if(!pn)throw Error("No answer extracted — Consensus may not have responded");if(Z.length===0)Z=await En(l);else{let p=await En(l),O=new Set(Z.map((D)=>D.url));for(let D of p)if(!O.has(D.url))Z.push(D)}let nt=await f(["eval",l,"document.location.href"]).catch(()=>"");u.durationMs=Date.now()-i,u.sourcePath=wn,_(u,"done",i),Jn({query:t,url:nt,answer:jn(pn,o),sources:Z,_envelope:en(u)})}catch(l){u.durationMs=Date.now()-i,xn(l,en(u))}}ue();
|