@duckmind/dm-darwin-x64 0.52.3 → 0.53.1

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.
Files changed (56) hide show
  1. package/dm +0 -0
  2. package/extensions/.dm-extensions.json +15 -8
  3. package/extensions/dm-cua/bin/browser-cua.mjs +6 -6
  4. package/extensions/dm-cua/index.js +5 -5
  5. package/extensions/dm-cua/src/browser-cua-lib.mjs +2 -2
  6. package/extensions/greedysearch-dm/bin/cdp-greedy.mjs +8 -1
  7. package/extensions/greedysearch-dm/bin/cdp-headless.mjs +1 -1
  8. package/extensions/greedysearch-dm/bin/cdp-visible.mjs +1 -1
  9. package/extensions/greedysearch-dm/bin/cdp.mjs +29 -20
  10. package/extensions/greedysearch-dm/bin/gschrome.mjs +1 -10
  11. package/extensions/greedysearch-dm/bin/kill-visible.mjs +1 -1
  12. package/extensions/greedysearch-dm/bin/launch-visible.mjs +1 -4
  13. package/extensions/greedysearch-dm/bin/launch.mjs +9 -5
  14. package/extensions/greedysearch-dm/bin/mcp.mjs +375 -0
  15. package/extensions/greedysearch-dm/bin/search.mjs +310 -156
  16. package/extensions/greedysearch-dm/bin/visible.mjs +1 -1
  17. package/extensions/greedysearch-dm/extractors/bing-copilot.mjs +205 -68
  18. package/extensions/greedysearch-dm/extractors/chatgpt.mjs +229 -140
  19. package/extensions/greedysearch-dm/extractors/common.mjs +160 -50
  20. package/extensions/greedysearch-dm/extractors/consensus.mjs +225 -92
  21. package/extensions/greedysearch-dm/extractors/consent.mjs +44 -17
  22. package/extensions/greedysearch-dm/extractors/gemini.mjs +275 -136
  23. package/extensions/greedysearch-dm/extractors/google-ai.mjs +172 -64
  24. package/extensions/greedysearch-dm/extractors/logically.mjs +183 -69
  25. package/extensions/greedysearch-dm/extractors/perplexity.mjs +331 -65
  26. package/extensions/greedysearch-dm/extractors/semantic-scholar.mjs +118 -41
  27. package/extensions/greedysearch-dm/index.js +20 -17
  28. package/extensions/greedysearch-dm/package.json +8 -3
  29. package/extensions/greedysearch-dm/skills/greedy-search/skill.md +8 -8
  30. package/extensions/greedysearch-dm/src/fetcher.mjs +2 -2
  31. package/extensions/greedysearch-dm/src/formatters/results.js +8 -6
  32. package/extensions/greedysearch-dm/src/github.mjs +7 -7
  33. package/extensions/greedysearch-dm/src/reddit.mjs +1 -1
  34. package/extensions/greedysearch-dm/src/search/browser-lifecycle.mjs +10 -9
  35. package/extensions/greedysearch-dm/src/search/challenge-detect.mjs +48 -0
  36. package/extensions/greedysearch-dm/src/search/chrome.mjs +129 -53
  37. package/extensions/greedysearch-dm/src/search/constants.mjs +8 -8
  38. package/extensions/greedysearch-dm/src/search/engines.mjs +9 -9
  39. package/extensions/greedysearch-dm/src/search/fetch-source.mjs +154 -77
  40. package/extensions/greedysearch-dm/src/search/minimize.mjs +1 -0
  41. package/extensions/greedysearch-dm/src/search/paths.mjs +1 -1
  42. package/extensions/greedysearch-dm/src/search/pdf.mjs +1 -1
  43. package/extensions/greedysearch-dm/src/search/port-pid.mjs +1 -0
  44. package/extensions/greedysearch-dm/src/search/progress.mjs +2 -0
  45. package/extensions/greedysearch-dm/src/search/recovery.mjs +1 -1
  46. package/extensions/greedysearch-dm/src/search/research.mjs +262 -167
  47. package/extensions/greedysearch-dm/src/search/scale-aware.mjs +11 -0
  48. package/extensions/greedysearch-dm/src/search/simple-research.mjs +827 -0
  49. package/extensions/greedysearch-dm/src/search/synthesis-runner.mjs +11 -11
  50. package/extensions/greedysearch-dm/src/search/synthesis.mjs +11 -11
  51. package/extensions/greedysearch-dm/src/tools/greedy-search-handler.js +23 -20
  52. package/extensions/greedysearch-dm/src/tools/shared.js +10 -9
  53. package/extensions/greedysearch-dm/src/utils/node-runtime.mjs +1 -1
  54. package/package.json +1 -1
  55. package/extensions/greedysearch-dm/src/search/cdp-endpoint.mjs +0 -3
  56. 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 Fn}from"node:crypto";import{spawn as En}from"node:child_process";import{dirname as dn,join as nr}from"node:path";import{fileURLToPath as rr}from"node:url";import{basename as ur}from"node:path";function fr(n=process.env,r=process.execPath){let u=n.GREEDY_SEARCH_NODE||n.NODE_BINARY||n.NODE;if(u?.trim())return u.trim();let f=ur(r||"").toLowerCase();if(f==="node"||f==="node.exe")return r;return"node"}var tr=dn(rr(import.meta.url)),ir=nr(tr,"..","bin","cdp.mjs");function b(n,r=30000){return S(n,null,r)}function S(n,r=null,u=30000){return new Promise((f,t)=>{let i=En(fr(),[ir,...n],{stdio:[r==null?"ignore":"pipe","pipe","pipe"]});if(r!=null)i.stdin.write(r),i.stdin.end();let g="",o="";i.stdout.on("data",(e)=>g+=e),i.stderr.on("data",(e)=>o+=e);let l=setTimeout(()=>{i.kill(),t(Error(`cdp timeout: ${n[0]}`))},u);i.on("close",(e)=>{if(clearTimeout(l),e===0)f(g.trim());else t(Error(o.trim()||`cdp exit ${e}`))})})}async function $n(n){if(n)return n;let r=(await b(["list"])).split(`
3
- `)[0]?.slice(0,8);if(!r)throw Error("No Chrome tabs found. Is Chrome running with --remote-debugging-port=9222?");let u=await b(["evalraw",r,"Target.createTarget",'{"url":"about:blank"}']),{targetId:f}=JSON.parse(u);await b(["list"]);let t=f.slice(0,8);try{await cn(t)}catch(i){process.stderr.write(`[getOrOpenTab] stealth injection failed: ${i.message}
4
- `)}return t}async function cn(n){await b(["evalraw",n,"Page.addScriptToEvaluateOnNewDocument",JSON.stringify({source:`
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 Fn}from"node:crypto";import{spawn as En}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 does not expose a useful webdriver value.
16
- // A literal false value is itself a common stealth tell; prefer undefined and
17
- // make the descriptor configurable like native browser properties.
18
- Object.defineProperty(navigator, 'webdriver', { get: () => undefined, configurable: true });
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
- var p = [
26
- { name: 'Chrome PDF Plugin', filename: 'internal-pdf-viewer', description: 'Portable Document Format' },
27
- { name: 'Chrome PDF Viewer', filename: 'mhjfbmdgcfjbbpaeojofohoefgiehjai', description: '' },
28
- { name: 'Native Client', filename: 'internal-nacl-plugin', description: '' },
29
- ];
30
- p.length = 3;
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
- var m = [
37
- { type: 'application/pdf', suffixes: 'pdf', description: 'Portable Document Format', enabledPlugin: null },
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 Fn}from"node:crypto";import{spawn as En}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 Fn}from"node:crypto";import{spawn as En}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 Fn}from"node:crypto";import{spawn as En}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 Fn}from"node:crypto";import{spawn as En}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() % 997) + Math.floor(Math.random() * 997)) & 1;
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 Fn}from"node:crypto";import{spawn as En}from"node:child_proc
116
163
  HTMLCanvasElement.prototype.toDataURL = __markNative(function toDataURL() {
117
164
  var ctx = this.getContext('2d');
118
165
  if (ctx) {
119
- // Add 1px noise pixel in corner (invisible but changes hash)
120
- var imgData = ctx.getImageData(0, 0, 1, 1);
121
- if (imgData) imgData.data[0] ^= __canvasNoise;
122
- ctx.putImageData(imgData, 0, 0);
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 Fn}from"node:crypto";import{spawn as En}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
- if (!screen.colorDepth) Object.defineProperty(screen, 'colorDepth', { get: () => 24, configurable: true });
139
- if (!screen.pixelDepth) Object.defineProperty(screen, 'pixelDepth', { get: () => 24, configurable: true });
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 Fn}from"node:crypto";import{spawn as En}from"node:child_proc
209
286
  };
210
287
  } catch(_) {}
211
288
  })();
212
- `})])}var F={postNav:800,postNavSlow:1200,postClick:300,postType:300,inputPoll:400,copyPoll:600,afterVerify:1500};function O(n){let r=n*0.4,u=Fn(-Math.floor(r),Math.floor(r)+1);return Math.max(50,Math.round(n+u))}async function Wn(n,r,u=15000,f=500){let t=String.raw`
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() + ${u};
215
- const _baseInterval = ${f};
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 Fn}from"node:crypto";import{spawn as En}from"node:child_proc
220
297
 
221
298
  function _poll() {
222
299
  try {
223
- if (document.querySelector('${r}')) { resolve(true); return; }
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 Fn}from"node:crypto";import{spawn as En}from"node:child_proc
228
305
 
229
306
  _poll();
230
307
  })
231
- `;return await b(["eval",n,t],u+5000)==="true"}async function jn(n){let r=n.indexOf("--stdin");if(r===-1)return n;let u=await new Promise((t)=>{let i="";process.stdin.setEncoding("utf8"),process.stdin.on("data",(g)=>i+=g),process.stdin.on("end",()=>t(i.trim()))}),f=[...n];return f[r]=u,f}function Qn(n){let r=n.includes("--short"),u=n.filter((o)=>o!=="--short"),f=u.indexOf("--tab"),t=f===-1?null:u[f+1];if(f!==-1)u=u.filter((o,l)=>l!==f&&l!==f+1);let i=u.indexOf("--locale"),g=i===-1?null:u[i+1];if(i!==-1)u=u.filter((o,l)=>l!==i&&l!==i+1);return{query:u.join(" "),tabPrefix:t,short:r,locale:g}}function Xn(n,r){if(!n.length||n[0]==="--help")process.stderr.write(r),process.exit(1)}function Jn(n,r,u=300){if(!r||n.length<=u)return n;let f=n.slice(0,u),t=f.lastIndexOf(" ");return t>0?`${f.slice(0,t)}…`:`${f}…`}function Zn(n){process.stdout.write(`${JSON.stringify(n,null,2)}
232
- `)}function c(n,r,u=null){if(!n||typeof n!=="object")return;let f=u?` (+${Date.now()-u}ms)`:"";if(n.lastStage=r,!Array.isArray(n.stages))n.stages=[];n.stages.push({stage:r,at:Date.now()});let t=n.engine||"extractor";console.error(`[${t}] stage: ${r}${f}`)}function E({engine:n,mode:r="headless",clipboardEmpty:u=null,fallbackUsed:f=null,blockedBy:t=null,verificationResult:i=null,inputReady:g=null,durationMs:o=null,lastStage:l=null,stages:e=null}={}){return{engine:n,mode:r,clipboardEmpty:u,fallbackUsed:f,blockedBy:t,verificationResult:i,inputReady:g,durationMs:o,lastStage:l,stages:e}}function xn(n,r=null){if(r){let u=JSON.stringify({_envelope:r,error:n.message});process.stdout.write(`${u}
233
- `)}process.stderr.write(`Error: ${n.message}
234
- `),process.exit(1)}import{readFileSync as Ir}from"node:fs";import{tmpdir as Sr}from"node:os";import{spawn as vr,execFileSync as Gn,execSync as en}from"node:child_process";import{existsSync as L,readFileSync as I,renameSync as Dr,unlinkSync as j,writeFileSync as P}from"node:fs";import bn from"node:http";import{platform as wn,tmpdir as Mr}from"node:os";import{join as Or}from"node:path";import{basename as gr}from"node:path";function qn(n=process.env,r=process.execPath){let u=n.GREEDY_SEARCH_NODE||n.NODE_BINARY||n.NODE;if(u?.trim())return u.trim();let f=gr(r||"").toLowerCase();if(f==="node"||f==="node.exe")return r;return"node"}import{existsSync as Bn}from"node:fs";import{platform as or}from"node:os";import{join as x}from"node:path";function h(n){let r=or()==="win32",u=process.env.SystemRoot||"C:\\Windows",f={win32:{powershell:x(u,"System32","WindowsPowerShell","v1.0","powershell.exe"),powershell_ise:x(u,"System32","WindowsPowerShell","v1.0","powershell_ise.exe"),netstat:x(u,"System32","netstat.exe"),taskkill:x(u,"System32","taskkill.exe"),tasklist:x(u,"System32","tasklist.exe"),cmd:x(u,"System32","cmd.exe")},unix:{ps:"/usr/bin/ps",lsof:"/usr/bin/lsof",ss:"/usr/sbin/ss",grep:"/usr/bin/grep",kill:"/usr/bin/kill"}},t=r?f.win32:f.unix,i=n.toLowerCase();if(t[i]&&Bn(t[i]))return t[i];if(r&&i==="netstat"){let g=x(u,"Sysnative","netstat.exe");if(Bn(g))return g}return n}import{existsSync as Y,mkdirSync as lr,readFileSync as an,writeFileSync as er}from"node:fs";import{homedir as br}from"node:os";import{join as Vn}from"node:path";import{tmpdir as z}from"node:os";var w=9222,q=`${z().replaceAll("\\","/")}/greedysearch-chrome-profile`,N=`${q}/DevToolsActivePort`,wr=`${z().replaceAll("\\","/")}/cdp-pages.json`,B=`${z().replaceAll("\\","/")}/greedysearch-chrome-mode`,_u=`${z().replaceAll("\\","/")}/greedysearch-visible-recovery.jsonl`,nn=Vn(br(),".dm"),W=Vn(nn,"greedyconfig"),rn=["perplexity","google","chatgpt"],un="gemini";function hr(){try{if(Y(W)){let n=an(W,"utf8"),r=JSON.parse(n);if(Array.isArray(r.engines)&&r.engines.length>0&&r.engines.every((u)=>typeof u==="string")){let u=r.engines.filter((t)=>d[t]),f=r.engines.filter((t)=>!d[t]);if(f.length>0)process.stderr.write(`[greedysearch] Warning: ignoring unknown engine(s) in ${W}: ${f.join(", ")}
235
- [greedysearch] Available engines: ${Object.keys(d).join(", ")}
236
- `);if(u.length>0)return u;process.stderr.write(`[greedysearch] Warning: no valid engines in ${W}, falling back to defaults: ${rn.join(", ")}
237
- `)}}}catch{}return rn}function $r(){try{if(!Y(nn))lr(nn,{recursive:!0});if(!Y(W))er(W,JSON.stringify({engines:rn,synthesizer:un},null,2)+`
238
- `,"utf8")}catch{}}$r();var _n=["gemini","chatgpt"];function cr(){try{if(Y(W)){let n=an(W,"utf8"),r=JSON.parse(n);if(typeof r.synthesizer==="string"){let u=r.synthesizer.toLowerCase();if(_n.includes(u))return u;process.stderr.write(`[greedysearch] Warning: unknown synthesizer "${r.synthesizer}" in ${W}
239
- [greedysearch] Available synthesizers: ${_n.join(", ")}
240
- [greedysearch] Falling back to default: ${un}
241
- `)}}}catch{}return un}var d={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"},au=hr();var Vu=cr(),Nu=Math.max(1,Number.parseInt(process.env.GREEDY_FETCH_CONCURRENCY||"5",10)||5);process.env.CDP_PROFILE_DIR=q;import{existsSync as yu,mkdirSync as Wr,readFileSync as kn,renameSync as jr,unlinkSync as Qr,writeFileSync as Hn}from"node:fs";import Xr from"node:http";import{platform as yn}from"node:os";import{dirname as Jr}from"node:path";var Kn=[9222,9223],Zr=/^(0|false|no|off)$/i;function xr(n){return[...new Set(n.filter(Boolean))]}function Nn(n,r="explicit"){let u=new URL(n),f=u.protocol==="wss:"?"wss:":"ws:",t=u.port?Number.parseInt(u.port,10):f==="wss:"?443:80;return{source:r,wsUrl:`${f}//${u.host}${u.pathname}${u.search}`,host:u.hostname,port:t,path:`${u.pathname}${u.search}`,httpUrl:`http://${u.hostname}:${t}`}}function Un(n=process.env){return![n.GREEDY_SEARCH_REUSE_EXISTING_BROWSER,n.DM_CUA_REUSE_EXISTING_BROWSER].some((r)=>r!==void 0&&Zr.test(String(r)))}function fn(n){let r=Number.parseInt(String(n??""),10);return Number.isInteger(r)&&r>0&&r<65536?r:null}function qr(n){if(!n)return null;let r=String(n).trim();if(!r)return null;let u=new URL(r.includes("://")?r:`http://${r}`),f=fn(u.port)||(u.protocol==="https:"?443:80);return{host:u.hostname,port:f,source:`env:${r}`}}function Br(n){if(!n)return[];return String(n).split(/[,\s]+/).map(fn).filter(Boolean)}function _r({env:n=process.env,platformName:r=yn(),procVersionText:u=null}={}){if(r!=="linux")return!1;if(n.WSL_DISTRO_NAME||n.WSL_INTEROP)return!0;let f=u??(()=>{try{return kn("/proc/version","utf8")}catch{return""}})();return/microsoft|wsl/i.test(f)}function ar({env:n=process.env,platformName:r=yn(),procVersionText:u=null,resolvConfText:f=null}={}){let t=["localhost","127.0.0.1"];if(_r({env:n,platformName:r,procVersionText:u})){let g=(f??(()=>{try{return kn("/etc/resolv.conf","utf8")}catch{return""}})()).match(/^\s*nameserver\s+([^\s#]+)/m);if(g)t.push(g[1]);t.push("host.docker.internal")}return xr(t)}function Vr({env:n=process.env,hosts:r=ar({env:n}),autoPorts:u=Kn,excludePorts:f=[]}={}){let t=[];for(let l of["GREEDY_SEARCH_CDP_WS_URL","DM_CUA_CDP_WS_URL","CDP_WS_URL"])if(n[l])t.push({wsUrl:n[l],source:`env:${l}`});for(let l of["GREEDY_SEARCH_CDP_URL","DM_CUA_CDP_URL","CDP_URL"])try{let e=qr(n[l]);if(e)t.push(e)}catch{}for(let l of["GREEDY_SEARCH_EXISTING_CDP_PORT","DM_CUA_EXISTING_CDP_PORT","GREEDY_SEARCH_CDP_PORT","DM_CUA_CDP_PORT"]){let e=fn(n[l]);if(!e)continue;for(let $ of r)t.push({host:$,port:e,source:`env:${l}`})}let i=Br(n.GREEDY_SEARCH_EXISTING_CDP_PORTS);for(let l of i)for(let e of r)t.push({host:e,port:l,source:"env:GREEDY_SEARCH_EXISTING_CDP_PORTS"});let g=new Set(f.filter(Boolean));if(Un(n))for(let l of u){if(g.has(l))continue;for(let e of r)t.push({host:e,port:l,source:"auto"})}let o=new Set;return t.filter((l)=>{let e=l.wsUrl||`${l.host}:${l.port}`;if(o.has(e))return!1;return o.add(e),!0})}async function Nr(n,{timeoutMs:r=700}={}){if(n.wsUrl)return Nn(n.wsUrl,n.source);let u=n.host||"localhost",f=n.port;if(!f)return null;let t=await new Promise((i)=>{let g=Xr.get({host:u,port:f,path:"/json/version",timeout:r},(o)=>{let l="";o.setEncoding("utf8"),o.on("data",(e)=>l+=e),o.on("end",()=>i(o.statusCode===200?l:null))});g.on("error",()=>i(null)),g.setTimeout(r,()=>{g.destroy(),i(null)})});if(!t)return null;try{let i=JSON.parse(t);if(!i.webSocketDebuggerUrl)return null;let g=Nn(i.webSocketDebuggerUrl,n.source),o=g.path||new URL(i.webSocketDebuggerUrl).pathname;return{...g,host:u,port:f,httpUrl:`http://${u}:${f}`,wsUrl:`ws://${u}:${f}${o}`,path:o}}catch{return null}}async function kr(n={}){for(let r of Vr(n)){let u=await Nr(r,n);if(u)return u}return null}function Hr(n){if(!n)throw Error("missing CDP endpoint");let r=new URL(n.wsUrl);return`${r.host}
242
- ${r.pathname}${r.search}
243
- `}function yr(n,r){Wr(Jr(n),{recursive:!0});let u=`${n}.tmp-${process.pid}`;Hn(u,Hr(r),"utf8");try{Qr(n)}catch{}jr(u,n)}async function sn({activePortFile:n,modeFile:r,env:u=process.env,excludePorts:f=[],autoPorts:t=Kn}={}){if(!Un(u))return null;let i=await kr({env:u,excludePorts:f,autoPorts:t});if(!i)return null;if(yr(n,i),r)Hn(r,"existing","utf8");return i}import{execFileSync as pn,execSync as tn}from"node:child_process";import{existsSync as m,mkdirSync as Kr,readFileSync as k,unlinkSync as a,writeFileSync as V}from"node:fs";import{platform as gn,tmpdir as On}from"node:os";var U=On().replaceAll("\\","/"),G=`${U}/greedysearch-chrome-metadata.json`,_=`${U}/greedysearch-chrome-launch.lock`,Ur=15000,R=`${U}/greedysearch-chrome.pid`,T=`${U}/greedysearch-chrome-mode`,y=`${U}/greedysearch-chrome-last-activity`;function K(n){if(!Number.isInteger(n)||n<=0)return!1;try{return process.kill(n,0),!0}catch{return!1}}function sr(n){if(!K(n))return null;try{if(gn()==="win32")return pn(h("powershell"),["-NoProfile","-NonInteractive","-Command",`(Get-CimInstance Win32_Process -Filter "ProcessId = ${n}").CommandLine`],{encoding:"utf8",windowsHide:!0,timeout:5000}).trim()||null;return pn(h("ps"),["-p",String(n),"-o","command="],{encoding:"utf8",timeout:5000}).trim()||null}catch{return null}}function pr(n,r,u=w){if(!n)return!1;let f=(g)=>String(g||"").replaceAll("\\","/").toLowerCase(),t=f(n),i=f(r);return t.includes(i)&&t.includes(`--remote-debugging-port=${u}`)&&!t.includes("--type=")}function An(n,r,u=w){return pr(sr(n),r,u)}function Ar(n=w){try{if(gn()==="win32"){let u=tn(`${h("netstat")} -ano -p TCP 2>nul`,{encoding:"utf8"}),f=new RegExp(String.raw`TCP\s+\S+:${n}\s+\S+:0\s+LISTENING\s+(\d+)`,"i"),t=u.match(f);return t?Number.parseInt(t[1],10):null}let r=tn(`${h("lsof")} -i :${n} -t 2>/dev/null || ${h("ss")} -tlnp 2>/dev/null | ${h("grep")} :${n} | ${h("grep")} -oP 'pid=\\K\\d+'`,{encoding:"utf8"}).trim();return r?Number.parseInt(r.split(`
244
- `)[0],10):null}catch{return null}}function vn(n){try{if(gn()==="win32")tn(`${h("taskkill")} /F /T /PID ${n}`,{stdio:"ignore"});else{try{process.kill(-n,"SIGKILL")}catch{}try{process.kill(n,"SIGKILL")}catch{}}return!0}catch{return!1}}function s(){try{if(m(G)){let n=k(G,"utf8"),r=JSON.parse(n);if(r&&typeof r.tempDir==="string"&&typeof r.debugPort==="number")return{browserPid:Number.isInteger(r.browserPid)?r.browserPid:void 0,debugPort:r.debugPort,tempDir:r.tempDir,clientPids:Array.isArray(r.clientPids)?r.clientPids.filter((u)=>Number.isInteger(u)&&u>0):[],sessionMode:r.sessionMode==="visible"?"visible":"headless",lastActivity:Number.isFinite(r.lastActivity)?r.lastActivity:0,launchedAt:Number.isFinite(r.launchedAt)?r.launchedAt:0}}}catch{}try{let n=m(R)?Number.parseInt(k(R,"utf8").trim(),10)||void 0:void 0,r=m(T)?k(T,"utf8").trim()==="visible"?"visible":"headless":"headless",u=m(y)?Number.parseInt(k(y,"utf8").trim(),10)||0:0;return{browserPid:n,debugPort:w,tempDir:q,clientPids:n?[n]:[],sessionMode:r,lastActivity:u,launchedAt:0}}catch{return null}}function C(n){try{V(G,JSON.stringify({browserPid:n.browserPid,debugPort:n.debugPort,tempDir:n.tempDir,clientPids:[...new Set(n.clientPids.filter((r)=>r>0))],sessionMode:n.sessionMode,lastActivity:n.lastActivity,launchedAt:n.launchedAt},null,2),"utf8")}catch{}try{if(n.browserPid)V(R,String(n.browserPid),"utf8")}catch{}try{V(T,n.sessionMode,"utf8")}catch{}try{V(y,String(n.lastActivity),"utf8")}catch{}}function Dn(){try{a(G)}catch{}try{a(R)}catch{}try{a(T)}catch{}try{a(y)}catch{}}function Yn(n){if(!n)return n;let r={...n,clientPids:[...new Set([...n.clientPids,process.pid].filter((u)=>K(u)||u===process.pid))]};return C(r),r}function on(n){let r=Date.now();try{if(n)C({...n,lastActivity:r});else V(y,String(r),"utf8")}catch{}}var Yu=Number.parseInt(process.env.GREEDY_SEARCH_IDLE_TIMEOUT_MINUTES||"5",10)||5;var Mn=!1;function zn(){if(Mn)return;Mn=!0;let n=s();if(!n)return;if(n.browserPid){if(!K(n.browserPid)){vn(n.browserPid),Dn();return}if(!An(n.browserPid,n.tempDir,n.debugPort))Dn();else C({...n,clientPids:n.clientPids.filter((t)=>K(t))})}let r=Ar();if(r&&r!==n.browserPid)if(An(r,q,w))C({browserPid:r,debugPort:w,tempDir:q,clientPids:[r],sessionMode:n.sessionMode,lastActivity:Date.now(),launchedAt:Date.now()});else vn(r)}function mn(){Kr(On(),{recursive:!0});try{let n=JSON.stringify({pid:process.pid,ts:Date.now()});return V(_,n,{encoding:"utf8",flag:"wx"}),{acquired:!0,release:()=>{try{let r=k(_,"utf8");if(JSON.parse(r).pid===process.pid)a(_)}catch{}}}}catch(n){if(n?.code!=="EEXIST")return{acquired:!1,release:()=>{}}}try{let n=k(_,"utf8"),r=JSON.parse(n),u=Date.now()-(r.ts||0);if(!K(r.pid)||u>Ur){try{a(_)}catch{}try{let t=JSON.stringify({pid:process.pid,ts:Date.now()});return V(_,t,{encoding:"utf8",flag:"wx"}),{acquired:!0,release:()=>{try{a(_)}catch{}}}}catch{return{acquired:!1,release:()=>{}}}}}catch{}return{acquired:!1,release:()=>{}}}var Yr=import.meta.dirname||new URL(".",import.meta.url).pathname.replace(/^\/([A-Z]:)/,"$1"),Tn=Mr().replaceAll("\\","/"),p=`${Tn}/greedysearch-chrome.pid`,A=`${Tn}/greedysearch-chrome-last-activity`,zr=Number.parseInt(process.env.GREEDY_SEARCH_IDLE_TIMEOUT_MINUTES||"5",10)||5,mr=Number.parseInt(process.env.GREEDY_SEARCH_VISIBLE_IDLE_TIMEOUT_MINUTES||"60",10)||60;function Gr(n,r=w){let u=String(n||"").toLowerCase();if(!u.includes(`--remote-debugging-port=${r}`)||u.includes("--type="))return null;return u.includes("--headless")}function Cn(){try{let n=hn(),r=n?Tr(n):null,u=Gr(r);if(u!==null){try{P(B,u?"headless":"visible","utf8")}catch{}return u}}catch{}try{if(!L(B))return!0;return I(B,"utf8").trim()==="headless"}catch{return!0}}function Rr(){try{P(A,String(Date.now()),"utf8")}catch{}try{let n=s();if(n)on(n)}catch{}}function Tr(n){try{if(wn()==="win32")return Gn(h("powershell"),["-NoProfile","-NonInteractive","-Command",`(Get-CimInstance Win32_Process -Filter "ProcessId = ${n}").CommandLine`],{encoding:"utf8",windowsHide:!0,timeout:5000}).trim()||null;return Gn(h("ps"),["-p",String(n),"-o","command="],{encoding:"utf8",timeout:5000}).trim()||null}catch{return null}}function hn(){try{if(wn()==="win32"){let r=en(`${h("netstat")} -ano -p TCP 2>nul`,{encoding:"utf8"}),u=new RegExp(String.raw`TCP\s+\S+:${w}\s+\S+:0\s+LISTENING\s+(\d+)`,"i"),f=r.match(u);return f?Number.parseInt(f[1],10):null}let n=en(`${h("lsof")} -i :${w} -t 2>/dev/null || ${h("ss")} -tlnp 2>/dev/null | ${h("grep")} :${w} | ${h("grep")} -oP 'pid=\\K\\d+'`,{encoding:"utf8"}).trim();return n?Number.parseInt(n.split(`
245
- `)[0],10):null}catch{return null}}async function Cr(n=1500){try{let u=await new Promise((t,i)=>{let g=bn.get(`http://localhost:${w}/json/version`,(o)=>{let l="";o.on("data",(e)=>l+=e),o.on("end",()=>{try{t(JSON.parse(l))}catch{i(Error("bad JSON"))}})});g.on("error",i),g.setTimeout(1000,()=>{g.destroy(),i(Error("timeout"))})}),f=new globalThis.WebSocket(u.webSocketDebuggerUrl);await new Promise((t)=>{f.onopen=()=>{f.send(JSON.stringify({id:1,method:"Browser.close"})),setTimeout(()=>{f.close(),t()},200)},f.onerror=()=>t(),setTimeout(t,1000)})}catch{}let r=Date.now()+n;while(Date.now()<r){if(!hn())return!0;await new Promise((f)=>setTimeout(f,150))}return Pr()}function Pr(){try{let n=hn();if(!n&&L(p))n=Number.parseInt(I(p,"utf8").trim(),10)||null;if(!n)return!1;if(wn()==="win32")en(`${h("taskkill")} /F /PID ${n}`,{stdio:"ignore"});else process.kill(n,"SIGKILL");return!0}catch{return!1}}async function Pn(){if(!await H(500)){try{j(p)}catch{}try{j(A)}catch{}try{j(B)}catch{}return!1}let r=await Cr(1500);try{j(p)}catch{}try{j(A)}catch{}try{j(B)}catch{}if(r)process.stderr.write(`[greedysearch] Killed Chrome on port ${w}.
246
- `);return r}var Rn=Pn;async function Lr(){let r=Cn()?zr:mr;if(r<=0)return!1;if(!L(A))return Rr(),!1;try{let u=Number.parseInt(I(A,"utf8").trim(),10);if(!u)return!1;if((Date.now()-u)/60000>=r)return Pn()}catch{}return!1}function H(n=3000){return new Promise((r)=>{let u=bn.get(`http://localhost:${w}/json/version`,(f)=>{f.resume(),r(f.statusCode===200)});u.on("error",()=>r(!1)),u.setTimeout(n,()=>{u.destroy(),r(!1)})})}async function ln(){let n=`${N}.lock`,r=`${N}.tmp`,u=5000,f=1000,t=await new Promise((i)=>{let g=Date.now(),o=()=>{try{let l=JSON.stringify({pid:process.pid,ts:Date.now()});P(n,l,{encoding:"utf8",flag:"wx"}),i(!0)}catch(l){if(l?.code!=="EEXIST"){if(Date.now()-g<1000)setTimeout(o,50);else i(!1);return}try{let e=I(n,"utf8").trim(),$=e.startsWith("{")?JSON.parse(e):{ts:Number(e)},Q=Number($?.ts)||0;if(Q>0&&Date.now()-Q>5000)try{j(n)}catch{}if(Date.now()-g<1000)setTimeout(o,50);else i(!1)}catch{if(Date.now()-g<1000)setTimeout(o,50);else i(!1)}}};o()});try{let i=await new Promise((e,$)=>{let Q=bn.get(`http://localhost:${w}/json/version`,(Z)=>{let v="";Z.on("data",(D)=>v+=D),Z.on("end",()=>e(v))});Q.on("error",$),Q.setTimeout(3000,()=>{Q.destroy(),$(Error("timeout"))})}),{webSocketDebuggerUrl:g}=JSON.parse(i),o=new URL(g),l=`${o.pathname}${o.search}`;if(t){P(r,`localhost:${w}
247
- ${l}`,"utf8");try{j(N)}catch{}Dr(r,N)}}catch{}finally{if(t)try{j(n)}catch{}}}async function Ln(){let n=L(p)||!!s(),r=await sn({activePortFile:N,modeFile:B,excludePorts:n?[w]:[]});if(r){process.stderr.write(`[greedysearch] Reusing existing browser CDP endpoint ${r.httpUrl} (${r.source}).
248
- `);return}zn();let u=await Lr(),f=u?!1:await H();if(!f&&!u)await new Promise((o)=>setTimeout(o,500)),f=await H();let t=!1;if(f){let o=Cn(),l=process.env.GREEDY_SEARCH_VISIBLE==="1";if(!l&&!o)process.stderr.write(`[greedysearch] Visible Chrome detected — switching to headless mode...
249
- `),await Rn(),await new Promise((e)=>setTimeout(e,1000)),t=!0;else if(l&&o)process.stderr.write(`[greedysearch] Headless Chrome detected switching to visible mode...
250
- `),await Rn(),await new Promise((e)=>setTimeout(e,1000)),t=!0}if(t?!1:await H()){await ln();try{let o=s();if(o)on(o),Yn(o)}catch{}return}let g=mn();if(!g.acquired){if(await new Promise((l)=>setTimeout(l,3000)),await H(5000)){await ln();return}}try{if(await H(1000)){await ln();return}process.stderr.write(`GreedySearch Chrome not running on port ${w} auto-launching...
251
- `);let l=[Or(Yr,"..","..","bin","launch.mjs")];if(process.env.GREEDY_SEARCH_VISIBLE!=="1")l.push("--headless");await new Promise((e,$)=>{vr(qn(),l,{stdio:["ignore",process.stderr,process.stderr]}).on("close",(Z)=>Z===0?e():$(Error("launch.mjs failed")))})}finally{g.release()}}var Fr="https://logically.app/research-assistant/",J={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 Er(n){return b(["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 dr(n){return await b(["eval",n,`(() => {
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 @@ ${l}`,"utf8");try{j(N)}catch{}Dr(r,N)}}catch{}finally{if(t)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 nu(n){try{await b(["list"]);let r=`${Sr().replaceAll("\\\\","/")}/cdp-pages.json`,f=JSON.parse(Ir(r,"utf8")).find((t)=>t.targetId?.startsWith(n))?.targetId;if(f)await b(["browse",n,"Target.activateTarget",JSON.stringify({targetId:f})]).catch(()=>null),await new Promise((t)=>setTimeout(t,250))}catch{}}async function ru(n,r){await nu(n);let u=await b(["eval",n,`(() => {
266
- const inputs = Array.from(document.querySelectorAll('${J.input}'));
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 @@ ${l}`,"utf8");try{j(N)}catch{}Dr(r,N)}}catch{}finally{if(t)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(!u)throw Error("Logically visible input not found");let f=JSON.parse(u);if(await b(["click",n,J.input]).catch(()=>null),await new Promise((i)=>setTimeout(i,O(120))),await b(["clickxy",n,String(f.x),String(f.y)]),await new Promise((i)=>setTimeout(i,O(F.postClick))),await S(["type",n,"--stdin"],r),await new Promise((i)=>setTimeout(i,O(F.postType))),await b(["eval",n,`Array.from(document.querySelectorAll('${J.input}')).some((el) => (el.innerText || '').length >= ${Math.floor(r.length*0.8)})`])!=="true")throw Error("Logically input did not accept text — input verification failed")}async function uu(n,r=90000){let u=String.raw`
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() + ${r};
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('${J.answerContainer}');
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 @@ ${l}`,"utf8");try{j(N)}catch{}Dr(r,N)}}catch{}finally{if(t)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 ${r}ms'));
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 b(["eval",n,u],r+1e4)}async function fu(n){let r=`(() => {
297
- const el = document.querySelector('${J.answerContainer}');
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 @@ ${l}`,"utf8");try{j(N)}catch{}Dr(r,N)}}catch{}finally{if(t)try{j(n)}catch{}}}asy
305
407
  answer: (el.innerText || '').trim(),
306
408
  answerHtml: clone.innerHTML,
307
409
  });
308
- })()`;return JSON.parse(await b(["eval",n,r],1e4))}async function tu(n){let r=String.raw`
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 @@ ${l}`,"utf8");try{j(N)}catch{}Dr(r,N)}}catch{}finally{if(t)try{j(n)}catch{}}}asy
445
547
  webCaptured: webSources.length,
446
548
  },
447
549
  });
448
- })()`,u=await b(["eval",n,r],20000);return JSON.parse(u)}async function iu(n){let r=String.raw`
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('${J.answerContainer}');
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 @@ ${l}`,"utf8");try{j(N)}catch{}Dr(r,N)}}catch{}finally{if(t)try{j(n)}catch{}}}asy
549
651
  }
550
652
  }
551
653
  return JSON.stringify(sources);
552
- })()`,u=await b(["eval",n,r],45000);return JSON.parse(u)}var gu=`Usage: node extractors/logically.mjs "<query>" [--tab <prefix>]
553
- `;async function ou(){let n=await jn(process.argv.slice(2));Xn(n,gu);let{query:r,tabPrefix:u,short:f}=Qn(n),t=Date.now(),g={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 Ln(),!u)await b(["list"]);let o=await $n(u),l=await b(["eval",o,"document.location.href"]).catch(()=>""),e=!1;try{let X=new URL(l).hostname.toLowerCase();e=X==="logically.app"||X.endsWith(".logically.app")}catch{}if(!e)c(g,"nav",t),await b(["nav",o,Fr],25000),await new Promise((X)=>setTimeout(X,900));c(g,"new-chat",t),await Er(o),await new Promise((X)=>setTimeout(X,700)),c(g,"input-wait",t);let $=await Wn(o,J.input,20000,400);if(g.inputReady=$,!$)throw Error("Logically input not found — page may not have loaded or is in unexpected state");if(c(g,"type-and-submit",t),await ru(o,r),await b(["eval",o,`(() => { const btn = document.querySelector('${J.submitButton}'); if (!btn) return 'missing'; btn.click(); return 'clicked'; })()`])!=="clicked")throw Error("Logically submit button not found");if(await new Promise((X)=>setTimeout(X,1500)),await dr(o))throw g.blockedBy="signin",g.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.");c(g,"answer-wait",t),await uu(o,90000),c(g,"extract-answer-html",t);let{answer:Z,answerHtml:v}=await fu(o);if(!Z)throw Error("No answer extracted — Logically may not have responded");c(g,"extract-inline-citations",t);let D=await iu(o);c(g,"extract-full-citations",t);let M=await tu(o),In=M.sources?.length?M.sources:D,Sn=await b(["eval",o,"document.location.href"]).catch(()=>"");g.durationMs=Date.now()-t,g.sourcePath=M.sources?.length?"citations-popover":"inline-citation-popovers",c(g,"done",t),Zn({query:r,url:Sn,answer:Jn(Z,f),answerHtml:v,sources:In,inlineSources:D,citationSummary:M.summary,_envelope:E(g)})}catch(o){g.durationMs=Date.now()-t,xn(o,E(g))}}ou();
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();