@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 Yt}from"node:crypto";import{spawn as Gt}from"node:child_process";import{basename as St}from"node:path";import{dirname as Rt,join as Lt}from"node:path";import{fileURLToPath as It}from"node:url";function Ft(t=process.env,e=process.execPath){let n=t.GREEDY_SEARCH_NODE||t.NODE_BINARY||t.NODE;if(n?.trim())return n.trim();let i=St(e||"").toLowerCase();if(i==="node"||i==="node.exe")return e;return"node"}var Et=Rt(It(import.meta.url)),te=Lt(Et,"..","bin","cdp.mjs"),ee=new Set(["list","snap","eval","shot","html","nav","net","click","clickxy","type","loadall","evalraw","browse","stop","--tab"]);function ne(t){if(!Array.isArray(t)||t.length===0)throw Error("cdp: args must be a non-empty array");if(t[0]==="test")return t.map((e,n)=>ft(e,n));if(!ee.has(t[0]))throw Error(`cdp: unknown subcommand '${t[0]}'`);return t.map((e,n)=>ft(e,n))}function ft(t,e){if(typeof t!=="string")throw Error(`cdp: argv[${e}] must be a string (got ${typeof t})`);if(t.includes("\x00"))throw Error(`cdp: argv[${e}] contains a null byte`);return t}function f(t,e=30000){return re(t,null,e)}function re(t,e=null,n=30000){let i=ne(t);return new Promise((r,l)=>{let o=Gt(Ft(),[te,...i],{stdio:[e==null?"ignore":"pipe","pipe","pipe"]});if(e!=null)o.stdin.write(e),o.stdin.end();let u="",a="";o.stdout.on("data",(g)=>u+=g),o.stderr.on("data",(g)=>a+=g);let s=setTimeout(()=>{o.kill(),l(Error(`cdp timeout: ${t[0]}`))},n);o.on("close",(g)=>{if(clearTimeout(s),g===0)r(u.trim());else l(Error(a.trim()||`cdp exit ${g}`))})})}function st(t,e){let n=(o)=>String(o??"").replace(/\s+/g," ").trim(),i=n(t),r=n(e);if(!r)return!1;if(i.length<Math.ceil(r.length*0.8))return!1;let l=Math.min(40,r.length);return i.includes(r.slice(0,l))&&i.includes(r.slice(-l))}async function gt(t){if(t)return t;let e=(await f(["list"])).split(`
|
|
3
|
+
`)[0]?.slice(0,8);if(!e)throw Error("No Chrome tabs found. Is Chrome running with --remote-debugging-port=9222?");let n=await f(["evalraw",e,"Target.createTarget",'{"url":"about:blank"}']),i;try{i=JSON.parse(n)}catch(o){throw Error(`Target.createTarget returned invalid JSON: ${o.message}`)}let{targetId:r}=i;if(!r)throw Error("Target.createTarget did not return a targetId");await f(["list"]);let l=r.slice(0,8);try{await ct(l)}catch(o){process.stderr.write(`[getOrOpenTab] stealth injection failed: ${o.message}
|
|
4
|
+
`)}return l}async function ct(t){await f(["evalraw",t,"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 nf}from"node:crypto";import{spawn as ff}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 nf}from"node:crypto";import{spawn as ff}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 nf}from"node:crypto";import{spawn as ff}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 nf}from"node:crypto";import{spawn as ff}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 nf}from"node:crypto";import{spawn as ff}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 nf}from"node:crypto";import{spawn as ff}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 nf}from"node:crypto";import{spawn as ff}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 nf}from"node:crypto";import{spawn as ff}from"node:child_proc
|
|
|
209
286
|
};
|
|
210
287
|
} catch(_) {}
|
|
211
288
|
})();
|
|
212
|
-
`})])}var
|
|
289
|
+
`})])}var I={postNav:800,postNavSlow:1200,postClick:300,postType:300,inputPoll:400,copyPoll:600,afterVerify:1500};function H(t){let e=t*0.2,n=Yt(-Math.floor(e),Math.floor(e)+1);return Math.max(50,Math.round(t+n))}async function pt(t,e,n=15000,i=500){let r=String.raw`
|
|
213
290
|
new Promise((resolve) => {
|
|
214
|
-
const _deadline = Date.now() + ${
|
|
215
|
-
const _baseInterval = ${
|
|
291
|
+
const _deadline = Date.now() + ${n};
|
|
292
|
+
const _baseInterval = ${i};
|
|
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 nf}from"node:crypto";import{spawn as ff}from"node:child_proc
|
|
|
220
297
|
|
|
221
298
|
function _poll() {
|
|
222
299
|
try {
|
|
223
|
-
if (document.querySelector('${
|
|
300
|
+
if (document.querySelector('${e}')) { resolve(true); return; }
|
|
224
301
|
if (Date.now() < _deadline) { setTimeout(_poll, _jitter(_baseInterval)); }
|
|
225
302
|
else { resolve(false); }
|
|
226
303
|
} catch(_) { resolve(false); }
|
|
@@ -228,33 +305,32 @@ import{randomInt as nf}from"node:crypto";import{spawn as ff}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{readFileSync as
|
|
235
|
-
[greedysearch] Available engines: ${Object.keys(
|
|
236
|
-
`);if(
|
|
237
|
-
`)}}}catch{}return
|
|
238
|
-
`,"utf8")}catch{}}
|
|
239
|
-
[greedysearch] Available synthesizers: ${
|
|
240
|
-
[greedysearch] Falling back to default: ${
|
|
241
|
-
`)}}}catch{}return
|
|
242
|
-
|
|
243
|
-
`}function
|
|
244
|
-
|
|
245
|
-
`)
|
|
246
|
-
`);return
|
|
247
|
-
${
|
|
248
|
-
`)
|
|
249
|
-
`),await
|
|
250
|
-
`)
|
|
251
|
-
`);let b=[Mn({moduleDir:gg,entrypoint:process.argv[1]})];if(process.env.GREEDY_SEARCH_VISIBLE!=="1")b.push("--headless");await new Promise((i,h)=>{Ef(xn(),b,{stdio:["ignore",process.stderr,process.stderr]}).on("close",(B)=>B===0?i():h(Error("launch.mjs failed")))})}finally{o.release()}}var hg="https://logically.app/research-assistant/",q={input:'.chat-control div.ProseMirror[contenteditable="true"][role="textbox"]',submitButton:'.chat-control button[class*="MuiButton-black"]',answerContainer:"#last-message .chat-content",citationSpan:"#last-message .chat-content span[title]"};async function Wg(n){return w(["eval",n,`(() => {
|
|
308
|
+
`;return await f(["eval",t,r],n+5000)==="true"}async function ht(t){let e=t.indexOf("--stdin");if(e===-1)return t;let n=await new Promise((r)=>{let l="";process.stdin.setEncoding("utf8"),process.stdin.on("data",(o)=>l+=o),process.stdin.on("end",()=>r(l.trim()))}),i=[...t];return i[e]=n,i}function bt(t){let e=t.includes("--short"),n=t.filter((u)=>u!=="--short"),i=n.indexOf("--tab"),r=i===-1?null:n[i+1];if(i!==-1)n=n.filter((u,a)=>a!==i&&a!==i+1);let l=n.indexOf("--locale"),o=l===-1?null:n[l+1];if(l!==-1)n=n.filter((u,a)=>a!==l&&a!==l+1);return{query:n.join(" "),tabPrefix:r,short:e,locale:o}}function wt(t,e){if(!t.length||t[0]==="--help")process.stderr.write(e),process.exit(1)}function yt(t,e,n=300){if(!e||t.length<=n)return t;let i=t.slice(0,n),r=i.lastIndexOf(" ");return r>0?`${i.slice(0,r)}…`:`${i}…`}function vt(t){process.stdout.write(`${JSON.stringify(t,null,2)}
|
|
309
|
+
`)}function w(t,e,n=null){if(!t||typeof t!=="object")return;let i=n?` (+${Date.now()-n}ms)`:"";if(t.lastStage=e,!Array.isArray(t.stages))t.stages=[];t.stages.push({stage:e,at:Date.now()});let r=t.engine||"extractor";console.error(`[${r}] stage: ${e}${i}`)}function E({engine:t,mode:e="headless",clipboardEmpty:n=null,fallbackUsed:i=null,blockedBy:r=null,verificationResult:l=null,inputReady:o=null,durationMs:u=null,lastStage:a=null,stages:s=null}={}){return{engine:t,mode:e,clipboardEmpty:n,fallbackUsed:i,blockedBy:r,verificationResult:l,inputReady:o,durationMs:u,lastStage:a,stages:s}}function mt(t,e=null){if(e){let n=JSON.stringify({_envelope:e,error:t.message});process.stdout.write(`${n}
|
|
310
|
+
`)}process.stderr.write(`Error: ${t.message}
|
|
311
|
+
`),process.exit(1)}import{readFileSync as Oe}from"node:fs";import{tmpdir as De}from"node:os";import{spawn as Xe,execFileSync as lt,execSync as dn}from"node:child_process";import{basename as ie}from"node:path";function _t(t=process.env,e=process.execPath){let n=t.GREEDY_SEARCH_NODE||t.NODE_BINARY||t.NODE;if(n?.trim())return n.trim();let i=ie(e||"").toLowerCase();if(i==="node"||i==="node.exe")return e;return"node"}import{existsSync as At,readFileSync as ut,renameSync as Ze,unlinkSync as m,writeFileSync as Y}from"node:fs";import at from"node:http";import{platform as Ot}from"node:os";import{join as qe}from"node:path";import{existsSync as xt}from"node:fs";import{platform as oe}from"node:os";import{join as $}from"node:path";function h(t){let e=oe()==="win32",n=process.env.SystemRoot||"C:\\Windows",i={win32:{powershell:$(n,"System32","WindowsPowerShell","v1.0","powershell.exe"),powershell_ise:$(n,"System32","WindowsPowerShell","v1.0","powershell_ise.exe"),netstat:$(n,"System32","netstat.exe"),taskkill:$(n,"System32","taskkill.exe"),tasklist:$(n,"System32","tasklist.exe"),cmd:$(n,"System32","cmd.exe")},unix:{ps:"/usr/bin/ps",lsof:"/usr/bin/lsof",ss:"/usr/sbin/ss",grep:"/usr/bin/grep",kill:"/usr/bin/kill"}},r=e?i.win32:i.unix,l=t.toLowerCase();if(r[l]&&xt(r[l]))return r[l];if(e&&l==="netstat"){let o=$(n,"Sysnative","netstat.exe");if(xt(o))return o}return t}import{execFileSync as le}from"node:child_process";import{platform as ue}from"node:os";function ae(t,e){return le(h(t),e,{encoding:"utf8",stdio:["ignore","pipe","ignore"],timeout:5000})}function fe(t){let e=String(t||"").match(/\b(\d+)\b/);return e?Number.parseInt(e[1],10):null}function se(t){return fe(t)}function ge(t,e){for(let n of String(t||"").split(/\r?\n/)){if(!/\bLISTEN\b/i.test(n))continue;if(!n.trim().split(/\s+/).slice(0,6).some((l)=>l.endsWith(`:${e}`)))continue;let r=n.match(/\bpid=(\d+)\b/);if(r)return Number.parseInt(r[1],10)}return null}function ce(t,e){for(let n of String(t||"").split(/\r?\n/)){let i=n.trim().split(/\s+/);if(i.length<5||i[0].toUpperCase()!=="TCP")continue;if(!i.at(-2)?.toUpperCase().startsWith("LISTEN"))continue;if(!i[1].endsWith(`:${e}`))continue;let r=Number.parseInt(i.at(-1),10);if(Number.isInteger(r)&&r>0)return r}return null}function tt(t,e,n){try{return t(e,n)}catch{return null}}function $t(t,{platformName:e=ue(),run:n=ae}={}){if(e==="win32")return ce(tt(n,"netstat",["-ano","-p","TCP"]),t);let i=tt(n,"lsof",["-nP",`-iTCP:${t}`,"-sTCP:LISTEN","-t"]),r=se(i);if(r)return r;if(e!=="linux")return null;return ge(tt(n,"ss",["-ltnp"]),t)}import{existsSync as M,mkdirSync as pe,readFileSync as jt,writeFileSync as he}from"node:fs";import{homedir as be}from"node:os";import{join as kt}from"node:path";import{tmpdir as we}from"node:os";function ye(t,e=9222){let n=Number.parseInt(String(t??""),10);return Number.isInteger(n)&&n>1024&&n<65535?n:e}var ve=we().replaceAll("\\","/"),c=ye(process.env.GREEDY_SEARCH_PORT),p=(process.env.GREEDY_SEARCH_PROFILE_DIR||process.env.CDP_PROFILE_DIR||`${ve}/greedysearch-chrome-profile`).replaceAll("\\","/"),Z=`${p}/DevToolsActivePort`,z=process.env.GREEDY_SEARCH_PID_FILE||`${p}/browser.pid`,me=process.env.CDP_PAGES_CACHE||`${p}/cdp-pages.json`,x=process.env.GREEDY_SEARCH_MODE_FILE||`${p}/browser-mode`,Jt=process.env.GREEDY_SEARCH_METADATA_FILE||`${p}/browser-metadata.json`,Nt=process.env.GREEDY_SEARCH_LAUNCH_LOCK_FILE||`${p}/browser-launch.lock`,U=process.env.GREEDY_SEARCH_ACTIVITY_FILE||`${p}/browser-last-activity`,_n=(process.env.CDP_SOCKET_DIR||`${p}/cdp-sockets`).replaceAll("\\","/"),xn=`${p}/visible-recovery.jsonl`,nt=kt(be(),".dm"),v=kt(nt,"greedyconfig"),rt=["perplexity","google","chatgpt","gemini"],it="gemini";function _e(){try{if(M(v)){let t=jt(v,"utf8"),e=JSON.parse(t);if(Array.isArray(e.engines)&&e.engines.length>0&&e.engines.every((n)=>typeof n==="string")){let n=e.engines.filter((r)=>et[r]),i=e.engines.filter((r)=>!et[r]);if(i.length>0)process.stderr.write(`[greedysearch] Warning: ignoring unknown engine(s) in ${v}: ${i.join(", ")}
|
|
312
|
+
[greedysearch] Available engines: ${Object.keys(et).join(", ")}
|
|
313
|
+
`);if(n.length>0)return n;process.stderr.write(`[greedysearch] Warning: no valid engines in ${v}, falling back to defaults: ${rt.join(", ")}
|
|
314
|
+
`)}}}catch{}return rt}function xe(){try{if(!M(nt))pe(nt,{recursive:!0});if(!M(v))he(v,JSON.stringify({engines:rt,synthesizer:it},null,2)+`
|
|
315
|
+
`,"utf8")}catch{}}xe();var Wt=["gemini","chatgpt"];function $e(){try{if(M(v)){let t=jt(v,"utf8"),e=JSON.parse(t);if(typeof e.synthesizer==="string"){let n=e.synthesizer.toLowerCase();if(Wt.includes(n))return n;process.stderr.write(`[greedysearch] Warning: unknown synthesizer "${e.synthesizer}" in ${v}
|
|
316
|
+
[greedysearch] Available synthesizers: ${Wt.join(", ")}
|
|
317
|
+
[greedysearch] Falling back to default: ${it}
|
|
318
|
+
`)}}}catch{}return it}var et={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"},$n=_e();var Wn=$e(),jn=Math.max(1,Number.parseInt(process.env.GREEDY_FETCH_CONCURRENCY||"5",10)||5);process.env.CDP_PROFILE_DIR=p;import{execFileSync as Xt,execSync as Zt}from"node:child_process";import{existsSync as A,mkdirSync as We,readFileSync as N,unlinkSync as j,writeFileSync as k}from"node:fs";import{platform as Vt}from"node:os";var O=Jt,W=Nt,je=15000,D=z,P=x,q=U;function B(t){if(!Number.isInteger(t)||t<=0)return!1;try{return process.kill(t,0),!0}catch{return!1}}function ke(t){if(!B(t))return null;try{if(Vt()==="win32")return Xt(h("powershell"),["-NoProfile","-NonInteractive","-Command",`(Get-CimInstance Win32_Process -Filter "ProcessId = ${t}").CommandLine`],{encoding:"utf8",windowsHide:!0,timeout:5000}).trim()||null;return Xt(h("ps"),["-p",String(t),"-o","command="],{encoding:"utf8",timeout:5000}).trim()||null}catch{return null}}function Je(t,e,n=c){if(!t)return!1;let i=(o)=>String(o||"").replaceAll("\\","/").toLowerCase(),r=i(t),l=i(e);return r.includes(l)&&r.includes(`--remote-debugging-port=${n}`)&&!r.includes("--type=")}function qt(t,e,n=c){return Je(ke(t),e,n)}function Ne(t=c){try{if(Vt()==="win32"){let n=Zt(`${h("netstat")} -ano -p TCP 2>nul`,{encoding:"utf8"}),i=new RegExp(String.raw`TCP\s+\S+:${t}\s+\S+:0\s+LISTENING\s+(\d+)`,"i"),r=n.match(i);return r?Number.parseInt(r[1],10):null}let e=Zt(`${h("lsof")} -i :${t} -t 2>/dev/null || ${h("ss")} -tlnp 2>/dev/null | ${h("grep")} :${t} | ${h("grep")} -oP 'pid=\\K\\d+'`,{encoding:"utf8"}).trim();return e?Number.parseInt(e.split(`
|
|
319
|
+
`)[0],10):null}catch{return null}}function Q(){try{if(A(O)){let t=N(O,"utf8"),e=JSON.parse(t);if(e&&typeof e.tempDir==="string"&&typeof e.debugPort==="number")return{browserPid:Number.isInteger(e.browserPid)?e.browserPid:void 0,debugPort:e.debugPort,tempDir:e.tempDir,clientPids:Array.isArray(e.clientPids)?e.clientPids.filter((n)=>Number.isInteger(n)&&n>0):[],sessionMode:e.sessionMode==="visible"?"visible":"headless",lastActivity:Number.isFinite(e.lastActivity)?e.lastActivity:0,launchedAt:Number.isFinite(e.launchedAt)?e.launchedAt:0}}}catch{}try{let t=A(D)?Number.parseInt(N(D,"utf8").trim(),10)||void 0:void 0,e=A(P)?N(P,"utf8").trim()==="visible"?"visible":"headless":"headless",n=A(q)?Number.parseInt(N(q,"utf8").trim(),10)||0:0;return{browserPid:t,debugPort:c,tempDir:p,clientPids:t?[t]:[],sessionMode:e,lastActivity:n,launchedAt:0}}catch{return null}}function T(t){try{k(O,JSON.stringify({browserPid:t.browserPid,debugPort:t.debugPort,tempDir:t.tempDir,clientPids:[...new Set(t.clientPids.filter((e)=>e>0))],sessionMode:t.sessionMode,lastActivity:t.lastActivity,launchedAt:t.launchedAt},null,2),"utf8")}catch{}try{if(t.browserPid)k(D,String(t.browserPid),"utf8")}catch{}try{k(P,t.sessionMode,"utf8")}catch{}try{k(q,String(t.lastActivity),"utf8")}catch{}}function Bt(){try{j(O)}catch{}try{j(D)}catch{}try{j(P)}catch{}try{j(q)}catch{}}function ot(t){if(!t)return t;let e={...t,clientPids:[...new Set([...t.clientPids,process.pid].filter((n)=>B(n)||n===process.pid))]};return T(e),e}function C(t){let e=Date.now();try{if(t)T({...t,lastActivity:e});else k(q,String(e),"utf8")}catch{}}var Bn=Number.parseInt(process.env.GREEDY_SEARCH_IDLE_TIMEOUT_MINUTES||"5",10)||5;var Qt=!1;function dt(){if(process.env.GREEDY_SEARCH_RESEARCH_CHILD)return;if(Qt)return;Qt=!0;let t=Q();if(!t)return;if(t.browserPid){if(!B(t.browserPid)){Bt();return}if(!qt(t.browserPid,t.tempDir,t.debugPort))Bt();else T({...t,clientPids:t.clientPids.filter((r)=>B(r))})}let e=Ne();if(e&&e!==t.browserPid)if(qt(e,p,c))T({browserPid:e,debugPort:c,tempDir:p,clientPids:[e],sessionMode:t.sessionMode,lastActivity:Date.now(),launchedAt:Date.now()});else process.stderr.write(`[greedysearch] Refusing to kill unverified listener ${e} on port ${c}.
|
|
320
|
+
`)}function Ht(){We(p,{recursive:!0});try{let t=JSON.stringify({pid:process.pid,ts:Date.now()});return k(W,t,{encoding:"utf8",flag:"wx"}),{acquired:!0,release:()=>{try{let e=N(W,"utf8");if(JSON.parse(e).pid===process.pid)j(W)}catch{}}}}catch(t){if(t?.code!=="EEXIST")return{acquired:!1,release:()=>{}}}try{let t=N(W,"utf8"),e=JSON.parse(t),n=Date.now()-(e.ts||0);if(!B(e.pid)||n>je){try{j(W)}catch{}try{let r=JSON.stringify({pid:process.pid,ts:Date.now()});return k(W,r,{encoding:"utf8",flag:"wx"}),{acquired:!0,release:()=>{try{j(W)}catch{}}}}catch{return{acquired:!1,release:()=>{}}}}}catch{}return{acquired:!1,release:()=>{}}}var Be=import.meta.dirname||new URL(".",import.meta.url).pathname.replace(/^\/([A-Z]:)/,"$1"),Mt=z,V=U,Qe=Number.parseInt(process.env.GREEDY_SEARCH_IDLE_TIMEOUT_MINUTES||"5",10)||5,Ve=Number.parseInt(process.env.GREEDY_SEARCH_VISIBLE_IDLE_TIMEOUT_MINUTES||"60",10)||60;function de(t,e=c){let n=String(t||"").toLowerCase();if(!n.includes(`--remote-debugging-port=${e}`)||n.includes("--type="))return null;return n.includes("--headless")}function Dt(){try{let t=S(),e=t?Pt(t):null,n=de(e);if(n!==null){try{Y(x,n?"headless":"visible","utf8")}catch{}return n}}catch{}try{if(!At(x))return!0;return ut(x,"utf8").trim()==="headless"}catch{return!0}}function He(){try{Y(V,String(Date.now()),"utf8")}catch{}try{let t=Q();if(t)C(t)}catch{}}function Pt(t){try{if(Ot()==="win32")return lt(h("powershell"),["-NoProfile","-NonInteractive","-Command",`(Get-CimInstance Win32_Process -Filter "ProcessId = ${t}").CommandLine`],{encoding:"utf8",windowsHide:!0,timeout:5000}).trim()||null;return lt(h("ps"),["-p",String(t),"-o","command="],{encoding:"utf8",timeout:5000}).trim()||null}catch{return null}}function Me(t){let e=String(t||"").replaceAll("\\","/"),n=p.replaceAll("\\","/");return e.includes(`--remote-debugging-port=${c}`)&&e.includes(`--user-data-dir=${n}`)&&!e.includes("--type=")}function S(){return $t(c)}function G(){let t=S();return t&&Me(Pt(t))?t:null}async function ze(t=1500){let e=G();if(!e)return process.stderr.write(`[greedysearch] Refusing to close an unverified listener.
|
|
321
|
+
`),!1;try{let i=await new Promise((l,o)=>{let u=at.get(`http://localhost:${c}/json/version`,(a)=>{let s="";a.on("data",(g)=>s+=g),a.on("end",()=>{try{l(JSON.parse(s))}catch{o(Error("bad JSON"))}})});u.on("error",o),u.setTimeout(1000,()=>{u.destroy(),o(Error("timeout"))})}),r=new globalThis.WebSocket(i.webSocketDebuggerUrl);await new Promise((l)=>{r.onopen=()=>{if(G()!==e){r.close(),l();return}r.send(JSON.stringify({id:1,method:"Browser.close"})),setTimeout(()=>{r.close(),l()},200)},r.onerror=()=>l(),setTimeout(l,1000)})}catch{}let n=Date.now()+t;while(Date.now()<n){let i=S();if(!i)return!0;if(i!==e)return!1;await new Promise((r)=>setTimeout(r,150))}return Ue(e)}function Ue(t=null){try{let e=G();if(!e||t&&e!==t)return!1;if(Ot()==="win32")lt(h("taskkill"),["/F","/PID",String(e)],{stdio:"ignore",windowsHide:!0});else process.kill(e,"SIGKILL");return!0}catch{return!1}}async function Tt(){if(!G()){if(S())process.stderr.write(`[greedysearch] Refusing to kill an unverified listener.
|
|
322
|
+
`);return!1}if(!await _(500)){try{m(Mt)}catch{}try{m(V)}catch{}try{m(x)}catch{}return!1}let e=await ze(1500);try{m(Mt)}catch{}try{m(V)}catch{}try{m(x)}catch{}if(e)process.stderr.write(`[greedysearch] Killed Chrome on port ${c}.
|
|
323
|
+
`);return e}var zt=Tt;async function Ae(){let e=Dt()?Qe:Ve;if(e<=0)return!1;if(!At(V))return He(),!1;try{let n=Number.parseInt(ut(V,"utf8").trim(),10);if(!n)return!1;if((Date.now()-n)/60000>=e)return Tt()}catch{}return!1}function _(t=3000){return new Promise((e)=>{let n=at.get(`http://localhost:${c}/json/version`,(i)=>{i.resume(),e(i.statusCode===200)});n.on("error",()=>e(!1)),n.setTimeout(t,()=>{n.destroy(),e(!1)})})}async function Ut(t=3000,e=200){let n=Date.now()+t;while(Date.now()<n){if(!await _(300))return!0;await new Promise((i)=>setTimeout(i,e))}return!await _(300)}async function K(){let t=`${Z}.lock`,e=`${Z}.tmp`,n=5000,i=1000,r=await new Promise((l)=>{let o=Date.now(),u=()=>{try{let a=JSON.stringify({pid:process.pid,ts:Date.now()});Y(t,a,{encoding:"utf8",flag:"wx"}),l(!0)}catch(a){if(a?.code!=="EEXIST"){if(Date.now()-o<1000)setTimeout(u,50);else l(!1);return}try{let s=ut(t,"utf8").trim(),g=s.startsWith("{")?JSON.parse(s):{ts:Number(s)},J=Number(g?.ts)||0;if(J>0&&Date.now()-J>5000)try{m(t)}catch{}if(Date.now()-o<1000)setTimeout(u,50);else l(!1)}catch{if(Date.now()-o<1000)setTimeout(u,50);else l(!1)}}};u()});try{let l=await new Promise((a,s)=>{let g=at.get(`http://localhost:${c}/json/version`,(J)=>{let X="";J.on("data",(F)=>X+=F),J.on("end",()=>a(X))});g.on("error",s),g.setTimeout(3000,()=>{g.destroy(),s(Error("timeout"))})}),{webSocketDebuggerUrl:o}=JSON.parse(l),u=new URL(o).pathname;if(r){Y(e,`${c}
|
|
324
|
+
${u}`,"utf8");try{m(Z)}catch{}Ze(e,Z)}}catch{}finally{if(r)try{m(t)}catch{}}}async function Ct(){if(process.env.GREEDY_SEARCH_RESEARCH_CHILD&&await _()){await K();try{let l=Q();if(l)C(l),ot(l)}catch{}return}dt();let t=await Ae(),e=t?!1:await _();if(!e&&!t)await new Promise((l)=>setTimeout(l,500)),e=await _();let n=!1;if(e){let l=Dt(),o=process.env.GREEDY_SEARCH_VISIBLE==="1";if(!o&&!l)process.stderr.write(`[greedysearch] Visible Chrome detected — switching to headless mode...
|
|
325
|
+
`),await zt(),await Ut(),n=!0;else if(o&&l)process.stderr.write(`[greedysearch] Headless Chrome detected — switching to visible mode...
|
|
326
|
+
`),await zt(),await Ut(),n=!0}if(n?!1:await _()){await K();try{let l=Q();if(l)C(l),ot(l)}catch{}return}let r=Ht();if(!r.acquired){let l=Date.now()+12000,o=!1;while(Date.now()<l){if(o=await _(500),o)break;await new Promise((u)=>setTimeout(u,250))}if(o){await K();return}}try{if(await _(1000)){await K();return}process.stderr.write(`GreedySearch Chrome not running on port ${c} — auto-launching...
|
|
327
|
+
`);let o=[qe(Be,"..","..","bin","launch.mjs")];if(process.env.GREEDY_SEARCH_VISIBLE!=="1")o.push("--headless");await new Promise((u,a)=>{Xe(_t(),o,{stdio:["ignore",process.stderr,process.stderr]}).on("close",(g)=>g===0?u():a(Error("launch.mjs failed")))})}finally{r.release()}}var Pe="https://logically.app/research-assistant/",y={input:'div.ProseMirror[contenteditable="true"]',submitButton:'.chat-control button[class*="MuiButton-black"], button[type="submit"]',answerContainer:'#last-message .chat-content, [class*="chat-content"]',citationSpan:'#last-message .chat-content span[title], [class*="chat-content"] span[title]'};async function Te(t){return f(["eval",t,`(() => {
|
|
252
328
|
const buttons = Array.from(document.querySelectorAll('button'));
|
|
253
329
|
const create = buttons.find((b) => (b.innerText || '').trim() === 'Create');
|
|
254
330
|
if (!create) return 'missing';
|
|
255
331
|
create.click();
|
|
256
332
|
return 'clicked';
|
|
257
|
-
})()`],5000).catch(()=>"error")}async function
|
|
333
|
+
})()`],5000).catch(()=>"error")}async function Ce(t){return await f(["eval",t,`(() => {
|
|
258
334
|
const url = document.location.href || '';
|
|
259
335
|
if (url.includes('/login') || url.includes('/signup') || url.includes('/sign-up')) return true;
|
|
260
336
|
const modalText = Array.from(document.querySelectorAll('[role="dialog"], .MuiModal-root'))
|
|
@@ -262,8 +338,8 @@ ${b}`,"utf8");try{J(k)}catch{}ng(f,k)}}catch{}finally{if(r)try{J(n)}catch{}}}asy
|
|
|
262
338
|
.join('
|
|
263
339
|
');
|
|
264
340
|
return /create a free account|continue with google|have an account[?] log in|log in|sign up/i.test(modalText);
|
|
265
|
-
})()`],5000).catch(()=>"false")==="true"}async function
|
|
266
|
-
const inputs = Array.from(document.querySelectorAll('${
|
|
341
|
+
})()`],5000).catch(()=>"false")==="true"}async function Ke(t){try{await f(["list"]);let e=`${De().replaceAll("\\\\","/")}/cdp-pages.json`,i=JSON.parse(Oe(e,"utf8")).find((r)=>r.targetId?.startsWith(t))?.targetId;if(i)await f(["browse",t,"Target.activateTarget",JSON.stringify({targetId:i})]).catch(()=>null),await new Promise((r)=>setTimeout(r,250))}catch{}}async function Ye(t,e){await Ke(t);let n=await f(["eval",t,`(() => {
|
|
342
|
+
const inputs = Array.from(document.querySelectorAll('${y.input}'));
|
|
267
343
|
const input = inputs.find((el) => {
|
|
268
344
|
const r = el.getBoundingClientRect();
|
|
269
345
|
return r.width > 20 && r.height > 5;
|
|
@@ -272,14 +348,40 @@ ${b}`,"utf8");try{J(k)}catch{}ng(f,k)}}catch{}finally{if(r)try{J(n)}catch{}}}asy
|
|
|
272
348
|
input.scrollIntoView({ block: 'center', inline: 'center' });
|
|
273
349
|
const r = input.getBoundingClientRect();
|
|
274
350
|
return JSON.stringify({ x: Math.round(r.left + Math.min(80, r.width / 2)), y: Math.round(r.top + r.height / 2) });
|
|
275
|
-
})()`]);if(!
|
|
351
|
+
})()`]);if(!n)throw Error("Logically visible input not found");let i;try{i=JSON.parse(n)}catch{throw Error("Logically input coordinates were invalid")}await f(["click",t,y.input]).catch(()=>null),await new Promise((a)=>setTimeout(a,H(120))),await f(["clickxy",t,String(i.x),String(i.y)]),await new Promise((a)=>setTimeout(a,H(I.postClick)));let r=async()=>{let a=await f(["eval",t,`(() => {
|
|
352
|
+
const ed = document.querySelector('${y.input}');
|
|
353
|
+
if (!ed) return 'no-input';
|
|
354
|
+
ed.focus();
|
|
355
|
+
if (!ed.editor || !ed.editor.commands) {
|
|
356
|
+
// Fallback to execCommand for non-tiptap editors
|
|
357
|
+
const ok = document.execCommand('insertText', false, ${JSON.stringify(e)});
|
|
358
|
+
return ok ? 'ok' : 'exec-failed';
|
|
359
|
+
}
|
|
360
|
+
const ok = ed.editor.commands.insertContent(${JSON.stringify(e)});
|
|
361
|
+
return ok ? 'ok' : 'tiptap-failed';
|
|
362
|
+
})()`],5000);if(a!=="ok")throw Error(`Logically type failed: ${a}`);await new Promise((s)=>setTimeout(s,H(I.postType)))},l=async()=>{let a=await f(["eval",t,`JSON.stringify(Array.from(document.querySelectorAll('${y.input}')).map((el) => el.innerText || el.textContent || ''))`]);try{return JSON.parse(a)}catch{return[]}},o=async()=>{return(await l()).some((s)=>st(s,e))},u=async()=>{await f(["eval",t,`(() => {
|
|
363
|
+
const ed = document.querySelector('${y.input}');
|
|
364
|
+
if (!ed) return false;
|
|
365
|
+
ed.focus();
|
|
366
|
+
if (ed.editor?.commands?.clearContent) {
|
|
367
|
+
ed.editor.commands.clearContent();
|
|
368
|
+
return true;
|
|
369
|
+
}
|
|
370
|
+
const range = document.createRange();
|
|
371
|
+
range.selectNodeContents(ed);
|
|
372
|
+
const selection = window.getSelection();
|
|
373
|
+
selection.removeAllRanges();
|
|
374
|
+
selection.addRange(range);
|
|
375
|
+
document.execCommand('delete');
|
|
376
|
+
return true;
|
|
377
|
+
})()`])};if(await r(),await o())return;if(await u(),await r(),!await o())throw Error("Logically input did not accept text — input verification failed")}async function Ge(t,e=90000){let n=String.raw`
|
|
276
378
|
new Promise((resolve, reject) => {
|
|
277
|
-
const deadline = Date.now() + ${
|
|
379
|
+
const deadline = Date.now() + ${e};
|
|
278
380
|
let last = '';
|
|
279
381
|
let stable = 0;
|
|
280
382
|
function poll() {
|
|
281
383
|
try {
|
|
282
|
-
const answer = document.querySelector('${
|
|
384
|
+
const answer = document.querySelector('${y.answerContainer}');
|
|
283
385
|
const text = (answer?.innerText || '').trim();
|
|
284
386
|
const body = document.body.innerText || '';
|
|
285
387
|
const stillGenerating = /Generating answer|Thinking\.\.\.|Searching the internet|Discovered \d+/.test(body) && text.length < 200;
|
|
@@ -289,12 +391,12 @@ ${b}`,"utf8");try{J(k)}catch{}ng(f,k)}}catch{}finally{if(r)try{J(n)}catch{}}}asy
|
|
|
289
391
|
if (stable >= 3) { resolve(text.length); return; }
|
|
290
392
|
}
|
|
291
393
|
if (Date.now() < deadline) setTimeout(poll, 700 + Math.random() * 250);
|
|
292
|
-
else reject(new Error('Logically answer did not stabilise within ${
|
|
394
|
+
else reject(new Error('Logically answer did not stabilise within ${e}ms'));
|
|
293
395
|
} catch (e) { reject(e); }
|
|
294
396
|
}
|
|
295
397
|
poll();
|
|
296
|
-
})`;return
|
|
297
|
-
const el = document.querySelector('${
|
|
398
|
+
})`;return f(["eval",t,n],e+1e4)}async function Se(t){let e=`(() => {
|
|
399
|
+
const el = document.querySelector('${y.answerContainer}');
|
|
298
400
|
if (!el) return JSON.stringify({ answer: '', answerHtml: '' });
|
|
299
401
|
const clone = el.cloneNode(true);
|
|
300
402
|
clone.querySelectorAll('svg').forEach((n) => n.remove());
|
|
@@ -305,7 +407,7 @@ ${b}`,"utf8");try{J(k)}catch{}ng(f,k)}}catch{}finally{if(r)try{J(n)}catch{}}}asy
|
|
|
305
407
|
answer: (el.innerText || '').trim(),
|
|
306
408
|
answerHtml: clone.innerHTML,
|
|
307
409
|
});
|
|
308
|
-
})()`;return JSON.parse(await
|
|
410
|
+
})()`;try{return JSON.parse(await f(["eval",t,e],1e4))}catch{return{answer:"",answerHtml:""}}}async function Fe(t){let e=String.raw`
|
|
309
411
|
(async () => {
|
|
310
412
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
311
413
|
|
|
@@ -445,10 +547,10 @@ ${b}`,"utf8");try{J(k)}catch{}ng(f,k)}}catch{}finally{if(r)try{J(n)}catch{}}}asy
|
|
|
445
547
|
webCaptured: webSources.length,
|
|
446
548
|
},
|
|
447
549
|
});
|
|
448
|
-
})()`,
|
|
550
|
+
})()`,n=await f(["eval",t,e],20000);try{return JSON.parse(n)}catch{return{sources:[],summary:{expectedTotal:0,reason:"invalid-json"}}}}async function Re(t){let e=String.raw`
|
|
449
551
|
(async () => {
|
|
450
552
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
451
|
-
const answer = document.querySelector('${
|
|
553
|
+
const answer = document.querySelector('${y.answerContainer}');
|
|
452
554
|
if (!answer) return JSON.stringify([]);
|
|
453
555
|
|
|
454
556
|
function parseUrlFromId(id) {
|
|
@@ -549,5 +651,17 @@ ${b}`,"utf8");try{J(k)}catch{}ng(f,k)}}catch{}finally{if(r)try{J(n)}catch{}}}asy
|
|
|
549
651
|
}
|
|
550
652
|
}
|
|
551
653
|
return JSON.stringify(sources);
|
|
552
|
-
})()`,
|
|
553
|
-
`;async function
|
|
654
|
+
})()`,n=await f(["eval",t,e],45000);try{return JSON.parse(n)}catch{return[]}}var Le=`Usage: node extractors/logically.mjs "<query>" [--tab <prefix>]
|
|
655
|
+
`;async function Ie(){let t=await ht(process.argv.slice(2));wt(t,Le);let{query:e,tabPrefix:n,short:i}=bt(t),r=Date.now(),o={engine:"logically",mode:process.env.GREEDY_SEARCH_VISIBLE==="1"?"visible":"headless",clipboardEmpty:null,fallbackUsed:null,blockedBy:null,verificationResult:null,inputReady:null};try{if(process.env.GREEDY_SEARCH_VISIBLE!=="1"&&process.env.GREEDY_SEARCH_ALWAYS_VISIBLE!=="1")process.env.GREEDY_SEARCH_HEADLESS="1";if(await Ct(),!n)await f(["list"]);let u=await gt(n),a=await f(["eval",u,"document.location.href"]).catch(()=>""),s=!1;try{let b=new URL(a).hostname.toLowerCase();s=b==="logically.app"||b.endsWith(".logically.app")}catch{}if(!s)w(o,"nav",r),await f(["nav",u,Pe],25000),await new Promise((b)=>setTimeout(b,900));w(o,"new-chat",r),await Te(u),await new Promise((b)=>setTimeout(b,700)),w(o,"input-wait",r);let g=await pt(u,y.input,20000,400);if(o.inputReady=g,!g)throw Error("Logically input not found — page may not have loaded or is in unexpected state");if(process.env.GREEDY_SEARCH_HEADLESS==="1"){let b=await f(["eval",u,`(() => {
|
|
656
|
+
const text = document.body?.innerText || '';
|
|
657
|
+
const m = text.match(/Chat messages\\s*\\n?\\s*(\\d+)\\s*\\/\\s*(\\d+)/i);
|
|
658
|
+
if (m && parseInt(m[1], 10) >= parseInt(m[2], 10)) {
|
|
659
|
+
return 'quota-exceeded';
|
|
660
|
+
}
|
|
661
|
+
// Also check if Create button is disabled
|
|
662
|
+
const createBtn = Array.from(document.querySelectorAll('button')).find(
|
|
663
|
+
(b) => b.innerText.trim() === 'Create',
|
|
664
|
+
);
|
|
665
|
+
if (createBtn && createBtn.disabled) return 'create-disabled';
|
|
666
|
+
return 'ok';
|
|
667
|
+
})()`],5000).catch(()=>"ok");if(b==="quota-exceeded"||b==="create-disabled")throw console.error("[logically] Rate Limited — skipping (visible retry won't help)"),o.blockedBy="rate-limit",Error("Rate Limited — Logically free message quota exhausted. Wait until reset.")}if(w(o,"type-and-submit",r),await Ye(u,e),await f(["eval",u,`(() => { const btn = document.querySelector('${y.submitButton}'); if (!btn) return 'missing'; btn.click(); return 'clicked'; })()`])!=="clicked")throw Error("Logically submit button not found");if(await new Promise((b)=>setTimeout(b,1500)),await Ce(u))throw o.blockedBy="signin",o.verificationResult="needs-human",Error("Logically login required — please log in or create a free account in the visible browser window. Once signed in, cookies persist for future runs.");w(o,"answer-wait",r),await Ge(u,90000),w(o,"extract-answer-html",r);let{answer:X,answerHtml:F}=await Se(u);if(!X)throw Error("No answer extracted — Logically may not have responded");w(o,"extract-full-citations",r);let d=await Fe(u),R=[],L=d.sources?.length?d.sources:null;if(!L)w(o,"extract-inline-citations",r),R=await Re(u),L=R;let Kt=await f(["eval",u,"document.location.href"]).catch(()=>"");o.durationMs=Date.now()-r,o.sourcePath=d.sources?.length?"citations-popover":"inline-citation-popovers",w(o,"done",r),vt({query:e,url:Kt,answer:yt(X,i),answerHtml:F,sources:L,inlineSources:R,citationSummary:d.summary,_envelope:E(o)})}catch(u){o.durationMs=Date.now()-r,mt(u,E(o))}}Ie();
|