@duckmind/dm-darwin-x64 0.52.6 → 0.53.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dm +0 -0
  2. package/extensions/.dm-extensions.json +14 -10
  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 -8
  11. package/extensions/greedysearch-dm/bin/kill-visible.mjs +1 -1
  12. package/extensions/greedysearch-dm/bin/launch-visible.mjs +1 -2
  13. package/extensions/greedysearch-dm/bin/launch.mjs +9 -11
  14. package/extensions/greedysearch-dm/bin/mcp.mjs +375 -0
  15. package/extensions/greedysearch-dm/bin/search.mjs +309 -157
  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 +226 -93
  21. package/extensions/greedysearch-dm/extractors/consent.mjs +44 -17
  22. package/extensions/greedysearch-dm/extractors/gemini.mjs +277 -138
  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 +23 -20
  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 -8
  35. package/extensions/greedysearch-dm/src/search/challenge-detect.mjs +48 -0
  36. package/extensions/greedysearch-dm/src/search/chrome.mjs +130 -54
  37. package/extensions/greedysearch-dm/src/search/constants.mjs +6 -6
  38. package/extensions/greedysearch-dm/src/search/engines.mjs +9 -9
  39. package/extensions/greedysearch-dm/src/search/fetch-source.mjs +160 -83
  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 -1
  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 +9 -9
  50. package/extensions/greedysearch-dm/src/search/synthesis.mjs +10 -10
  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/search/launcher-paths.mjs +0 -3
  57. package/extensions/greedysearch-dm/src/search/partial-output.mjs +0 -1
  58. package/extensions/greedysearch-dm/src/utils/browser-executable.mjs +0 -1
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{spawn as E}from"node:child_process";import{basename as Q}from"node:path";function A(z=process.env,q=process.execPath){let H=z.GREEDY_SEARCH_NODE||z.NODE_BINARY||z.NODE;if(H?.trim())return H.trim();let K=Q(q||"").toLowerCase();if(K==="node"||K==="node.exe")return q;return"node"}var F=new URL("./launch-visible.mjs",import.meta.url).pathname.replace(/^\/([A-Z]:)/,"$1"),O=process.argv[2]||"";if(O==="--kill")E(A(),[F,"--kill"],{stdio:"inherit"}).on("close",(q)=>process.exit(q??0));else if(O==="--status")E(A(),[F,"--status"],{stdio:"inherit"}).on("close",(q)=>process.exit(q??0));else console.log("\uD83D\uDE80 Launching visible GreedySearch Chrome..."),E(A(),[F],{stdio:"inherit",env:{...process.env,GREEDY_SEARCH_VISIBLE:"1"}}).on("close",(q)=>process.exit(q??0));
2
+ import{spawn as F}from"node:child_process";import{basename as L}from"node:path";function E(z=process.env,q=process.execPath){let I=z.GREEDY_SEARCH_NODE||z.NODE_BINARY||z.NODE;if(I?.trim())return I.trim();let J=L(q||"").toLowerCase();if(J==="node"||J==="node.exe")return q;return"node"}var H=new URL("./launch-visible.mjs",import.meta.url).pathname.replace(/^\/([A-Z]:)/,"$1"),K=process.argv[2]||"";if(K==="--kill")F(E(),[H,"--kill"],{stdio:"inherit"}).on("close",(q)=>process.exit(q??0));else if(K==="--status")F(E(),[H,"--status"],{stdio:"inherit"}).on("close",(q)=>process.exit(q??0));else console.log("\uD83D\uDE80 Launching visible GreedySearch Chrome..."),F(E(),[H],{stdio:"inherit",env:{...process.env,GREEDY_SEARCH_VISIBLE:"1"}}).on("close",(q)=>process.exit(q??0));
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import{randomInt as r}from"node:crypto";import{spawn as t}from"node:child_process";import{dirname as e,join as ZZ}from"node:path";import{fileURLToPath as $Z}from"node:url";import{basename as a}from"node:path";function k(Z=process.env,X=process.execPath){let K=Z.GREEDY_SEARCH_NODE||Z.NODE_BINARY||Z.NODE;if(K?.trim())return K.trim();let $=a(X||"").toLowerCase();if($==="node"||$==="node.exe")return X;return"node"}var KZ=e($Z(import.meta.url)),XZ=ZZ(KZ,"..","bin","cdp.mjs");function N(Z,X=30000){return QZ(Z,null,X)}function QZ(Z,X=null,K=30000){return new Promise(($,Q)=>{let H=t(k(),[XZ,...Z],{stdio:[X==null?"ignore":"pipe","pipe","pipe"]});if(X!=null)H.stdin.write(X),H.stdin.end();let z="",W="";H.stdout.on("data",(Y)=>z+=Y),H.stderr.on("data",(Y)=>W+=Y);let J=setTimeout(()=>{H.kill(),Q(Error(`cdp timeout: ${Z[0]}`))},K);H.on("close",(Y)=>{if(clearTimeout(J),Y===0)$(z.trim());else Q(Error(W.trim()||`cdp exit ${Y}`))})})}async function F(Z){if(Z)return Z;let K=(await N(["list"])).split(`
3
- `)[0]?.slice(0,8);if(!K)throw Error("No Chrome tabs found. Is Chrome running with --remote-debugging-port=9222?");let $=await N(["evalraw",K,"Target.createTarget",'{"url":"about:blank"}']),{targetId:Q}=JSON.parse($);await N(["list"]);let H=Q.slice(0,8);try{await zZ(H)}catch(z){process.stderr.write(`[getOrOpenTab] stealth injection failed: ${z.message}
4
- `)}return H}async function I(Z,X){let K=`
2
+ import{randomInt as KZ}from"node:crypto";import{spawn as QZ}from"node:child_process";import{basename as $Z}from"node:path";function k(Z=process.env,Q=process.execPath){let K=Z.GREEDY_SEARCH_NODE||Z.NODE_BINARY||Z.NODE;if(K?.trim())return K.trim();let $=$Z(Q||"").toLowerCase();if($==="node"||$==="node.exe")return Q;return"node"}import{dirname as HZ,join as XZ}from"node:path";import{fileURLToPath as WZ}from"node:url";var JZ=HZ(WZ(import.meta.url)),UZ=XZ(JZ,"..","bin","cdp.mjs"),YZ=new Set(["list","snap","eval","shot","html","nav","net","click","clickxy","type","loadall","evalraw","browse","stop","--tab"]);function GZ(Z){if(!Array.isArray(Z)||Z.length===0)throw Error("cdp: args must be a non-empty array");if(Z[0]==="test")return Z.map((Q,K)=>R(Q,K));if(!YZ.has(Z[0]))throw Error(`cdp: unknown subcommand '${Z[0]}'`);return Z.map((Q,K)=>R(Q,K))}function R(Z,Q){if(typeof Z!=="string")throw Error(`cdp: argv[${Q}] must be a string (got ${typeof Z})`);if(Z.includes("\x00"))throw Error(`cdp: argv[${Q}] contains a null byte`);return Z}function G(Z,Q=30000){return DZ(Z,null,Q)}function DZ(Z,Q=null,K=30000){let $=GZ(Z);return new Promise((H,J)=>{let X=QZ(k(),[UZ,...$],{stdio:[Q==null?"ignore":"pipe","pipe","pipe"]});if(Q!=null)X.stdin.write(Q),X.stdin.end();let W="",U="";X.stdout.on("data",(D)=>W+=D),X.stderr.on("data",(D)=>U+=D);let Y=setTimeout(()=>{X.kill(),J(Error(`cdp timeout: ${Z[0]}`))},K);X.on("close",(D)=>{if(clearTimeout(Y),D===0)H(W.trim());else J(Error(U.trim()||`cdp exit ${D}`))})})}async function w(Z){if(Z)return Z;let K=(await G(["list"])).split(`
3
+ `)[0]?.slice(0,8);if(!K)throw Error("No Chrome tabs found. Is Chrome running with --remote-debugging-port=9222?");let $=await G(["evalraw",K,"Target.createTarget",'{"url":"about:blank"}']),H;try{H=JSON.parse($)}catch(W){throw Error(`Target.createTarget returned invalid JSON: ${W.message}`)}let{targetId:J}=H;if(!J)throw Error("Target.createTarget did not return a targetId");await G(["list"]);let X=J.slice(0,8);try{await OZ(X)}catch(W){process.stderr.write(`[getOrOpenTab] stealth injection failed: ${W.message}
4
+ `)}return X}async function f(Z,Q){let K=`
5
5
  (() => {
6
- window.${X} = null;
6
+ window.${Q} = null;
7
7
  const _clipboard = navigator.clipboard;
8
8
  if (!_clipboard) return;
9
9
  const _origWriteText = typeof _clipboard.writeText === 'function'
@@ -14,7 +14,7 @@ import{randomInt as r}from"node:crypto";import{spawn as t}from"node:child_proces
14
14
  : null;
15
15
 
16
16
  _clipboard.writeText = function(text) {
17
- window.${X} = String(text ?? '');
17
+ window.${Q} = String(text ?? '');
18
18
  if (!_origWriteText) return Promise.resolve();
19
19
  // The OS/browser clipboard write may be denied in automated Chrome or
20
20
  // when the tab is not focused. We only need the captured text; returning
@@ -28,7 +28,7 @@ import{randomInt as r}from"node:crypto";import{spawn as t}from"node:child_proces
28
28
  for (const item of items || []) {
29
29
  if (item.types && item.types.includes('text/plain')) {
30
30
  const blob = await item.getType('text/plain');
31
- window.${X} = await blob.text();
31
+ window.${Q} = await blob.text();
32
32
  break;
33
33
  }
34
34
  }
@@ -38,7 +38,26 @@ import{randomInt as r}from"node:crypto";import{spawn as t}from"node:child_proces
38
38
  catch (_) { return undefined; }
39
39
  };
40
40
  })();
41
- `;await N(["eval",Z,K])}async function zZ(Z){await N(["evalraw",Z,"Page.addScriptToEvaluateOnNewDocument",JSON.stringify({source:`
41
+ `;await G(["eval",Z,K])}async function y(Z,Q,K,$={}){let{timeoutMs:H=2600}=$,J=$.retryClick!=null?$.retryClick:Math.floor(H*0.4),X=String.raw`
42
+ new Promise((resolve) => {
43
+ const _deadline = Date.now() + ${H};
44
+ const _retryAt = Date.now() + ${J};
45
+ let _retried = false;
46
+ function _click() { try { ${Q}; } catch(_) {} }
47
+ function _poll() {
48
+ const val = window.${K};
49
+ if (val) { resolve(val); return; }
50
+ if (!_retried && Date.now() >= _retryAt) {
51
+ _retried = true;
52
+ _click();
53
+ }
54
+ if (Date.now() < _deadline) { setTimeout(_poll, 100); }
55
+ else { resolve(window.${K} || ''); }
56
+ }
57
+ _click();
58
+ _poll();
59
+ })
60
+ `;return await G(["eval",Z,X],H+5000).catch(()=>"")}async function OZ(Z){await G(["evalraw",Z,"Page.addScriptToEvaluateOnNewDocument",JSON.stringify({source:`
42
61
  (function() {
43
62
  // ── Runtime.enable / CDP detection masking ──────────────
44
63
  try { delete window.__REBROWSER_RUNTIME_ENABLE; } catch(_) {}
@@ -49,40 +68,62 @@ import{randomInt as r}from"node:crypto";import{spawn as t}from"node:child_proces
49
68
  try { delete window._phantom; } catch(_) {}
50
69
  try { delete window.Buffer; } catch(_) {}
51
70
 
52
- // Real Chrome without automation does not expose a useful webdriver value.
53
- // A literal false value is itself a common stealth tell; prefer undefined and
54
- // make the descriptor configurable like native browser properties.
55
- Object.defineProperty(navigator, 'webdriver', { get: () => undefined, configurable: true });
71
+ // Real Chrome without automation should not expose navigator.webdriver at all.
72
+ // A literal false or an own-property getter returning undefined is itself a
73
+ // common stealth tell; remove both instance and prototype properties when the
74
+ // descriptor is configurable (as it is with --disable-blink-features).
75
+ try { delete navigator.webdriver; } catch(_) {}
76
+ try { delete Navigator.prototype.webdriver; } catch(_) {}
56
77
  Object.defineProperty(navigator, 'vendor', { get: () => 'Google Inc.', configurable: true });
57
78
  Object.defineProperty(navigator, 'platform', { get: () => 'Win32', configurable: true });
58
79
  Object.defineProperty(navigator, 'maxTouchPoints', { get: () => 0, configurable: true });
59
80
  Object.defineProperty(navigator, 'pdfViewerEnabled', { get: () => true, configurable: true });
81
+ Object.defineProperty(navigator, 'productSub', { get: () => '20030107', configurable: true });
82
+ Object.defineProperty(navigator, 'product', { get: () => 'Gecko', configurable: true });
83
+ var __greedyMimeTypes = null;
84
+ function __makeMimeTypes() {
85
+ var pdf = { type: 'application/pdf', suffixes: 'pdf', description: 'Portable Document Format', enabledPlugin: null };
86
+ var textPdf = { type: 'text/pdf', suffixes: 'pdf', description: 'Portable Document Format', enabledPlugin: null };
87
+ try { Object.setPrototypeOf(pdf, MimeType.prototype); } catch(_) {}
88
+ try { Object.setPrototypeOf(textPdf, MimeType.prototype); } catch(_) {}
89
+ var m = [pdf, textPdf];
90
+ try { Object.setPrototypeOf(m, MimeTypeArray.prototype); } catch(_) {}
91
+ m.item = function item(i) { return this[i] || null; };
92
+ m.namedItem = function namedItem(name) { return Array.prototype.find.call(this, function(x) { return x && x.type === name; }) || null; };
93
+ return m;
94
+ }
60
95
  Object.defineProperty(navigator, 'plugins', {
61
96
  get: () => {
62
- var p = [
63
- { name: 'Chrome PDF Plugin', filename: 'internal-pdf-viewer', description: 'Portable Document Format' },
64
- { name: 'Chrome PDF Viewer', filename: 'mhjfbmdgcfjbbpaeojofohoefgiehjai', description: '' },
65
- { name: 'Native Client', filename: 'internal-nacl-plugin', description: '' },
66
- ];
67
- p.length = 3;
97
+ __greedyMimeTypes = __greedyMimeTypes || __makeMimeTypes();
98
+ var plugin0 = { name: 'Chrome PDF Plugin', filename: 'internal-pdf-viewer', description: 'Portable Document Format' };
99
+ var plugin1 = { name: 'Chrome PDF Viewer', filename: 'mhjfbmdgcfjbbpaeojofohoefgiehjai', description: '' };
100
+ var plugin2 = { name: 'Native Client', filename: 'internal-nacl-plugin', description: '' };
101
+ try { Object.setPrototypeOf(plugin0, Plugin.prototype); } catch(_) {}
102
+ try { Object.setPrototypeOf(plugin1, Plugin.prototype); } catch(_) {}
103
+ try { Object.setPrototypeOf(plugin2, Plugin.prototype); } catch(_) {}
104
+ var p = [plugin0, plugin1, plugin2];
105
+ p.item = function item(i) { return this[i] || null; };
106
+ p.namedItem = function namedItem(name) { return Array.prototype.find.call(this, function(x) { return x && x.name === name; }) || null; };
107
+ p.refresh = function refresh() {};
108
+ try { Object.setPrototypeOf(p, PluginArray.prototype); } catch(_) {}
109
+ try {
110
+ __greedyMimeTypes[0].enabledPlugin = p[0];
111
+ __greedyMimeTypes[1].enabledPlugin = p[0];
112
+ } catch(_) {}
68
113
  return p;
69
114
  },
115
+ configurable: true,
70
116
  });
71
117
  Object.defineProperty(navigator, 'mimeTypes', {
72
118
  get: () => {
73
- var m = [
74
- { type: 'application/pdf', suffixes: 'pdf', description: 'Portable Document Format', enabledPlugin: null },
75
- { type: 'text/pdf', suffixes: 'pdf', description: 'Portable Document Format', enabledPlugin: null },
76
- ];
77
- m.item = function(i) { return m[i] || null; };
78
- m.namedItem = function(name) { return m.find(function(x) { return x.type === name; }) || null; };
79
- return m;
119
+ __greedyMimeTypes = __greedyMimeTypes || __makeMimeTypes();
120
+ return __greedyMimeTypes;
80
121
  },
81
122
  configurable: true,
82
123
  });
83
124
  Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'], configurable: true });
84
125
  try {
85
- Object.defineProperty(navigator, 'connection', { get: () => ({ effectiveType: '4g', rtt: 50, downlink: 10, saveData: false }), configurable: true });
126
+ Object.defineProperty(navigator, 'connection', { get: () => ({ effectiveType: '4g', rtt: 50, downlink: 10, downlinkMax: Infinity, saveData: false }), configurable: true });
86
127
  } catch(_) {}
87
128
  if (!navigator.mediaDevices) {
88
129
  Object.defineProperty(navigator, 'mediaDevices', {
@@ -98,6 +139,18 @@ import{randomInt as r}from"node:crypto";import{spawn as t}from"node:child_proces
98
139
  configurable: true,
99
140
  });
100
141
  }
142
+ // ── Missing platform APIs (headless often lacks these) ─
143
+ try {
144
+ if (!navigator.share) {
145
+ navigator.share = function() { return Promise.reject(new Error('NotAllowedError')); };
146
+ }
147
+ } catch(_) {}
148
+ try {
149
+ if (!navigator.contentIndex) {
150
+ Object.defineProperty(navigator, 'contentIndex', { get: () => ({ add: function() {}, delete: function() {}, getAll: function() { return Promise.resolve([]); } }), configurable: true });
151
+ }
152
+ } catch(_) {}
153
+
101
154
  if (!window.chrome) {
102
155
  window.chrome = {
103
156
  app: { isInstalled: false, InstallState: {}, RunningState: {} },
@@ -105,8 +158,8 @@ import{randomInt as r}from"node:crypto";import{spawn as t}from"node:child_proces
105
158
  OnInstalledReason: {}, OnRestartRequiredReason: {}, PlatformArch: {}, PlatformNaclArch: {}, PlatformOs: {}, RequestUpdateCheckStatus: {},
106
159
  connect: () => ({}), sendMessage: () => {}, onMessage: { addListener: () => {} }
107
160
  },
108
- loadTimes: () => ({}),
109
- csi: () => ({}),
161
+ 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' }; },
162
+ csi: function() { var t = Date.now(); return { onloadT: t - 2000, startE: t - 5000, pageT: 'back', tran: 2 }; },
110
163
  };
111
164
  }
112
165
  var __greedyNativeFns = [];
@@ -127,6 +180,19 @@ import{randomInt as r}from"node:crypto";import{spawn as t}from"node:child_proces
127
180
  return getParam.call(this, p);
128
181
  });
129
182
  } catch(_) {}
183
+ // ── WebGL readPixels noise ──────────────────────────
184
+ // CreepJS and other fingerprinters draw content with WebGL and read back the
185
+ // rendered pixels. Adding subtle noise breaks rendering-based fingerprinting.
186
+ try {
187
+ var origReadPixels = WebGLRenderingContext.prototype.readPixels;
188
+ WebGLRenderingContext.prototype.readPixels = __markNative(function readPixels(x, y, width, height, format, type, pixels) {
189
+ var result = origReadPixels.call(this, x, y, width, height, format, type, pixels);
190
+ if (pixels && pixels.length > 0) {
191
+ pixels[0] ^= 1;
192
+ }
193
+ return result;
194
+ });
195
+ } catch(_) {}
130
196
  Object.defineProperty(navigator, 'hardwareConcurrency', { get: () => 8, configurable: true });
131
197
  Object.defineProperty(navigator, 'deviceMemory', { get: () => 8, configurable: true });
132
198
 
@@ -134,7 +200,7 @@ import{randomInt as r}from"node:crypto";import{spawn as t}from"node:child_proces
134
200
  // Headless rendering engines produce slightly different canvas output
135
201
  // than headed Chrome. Subtle noise breaks hash-based fingerprinting.
136
202
  try {
137
- var __canvasNoise = ((Date.now() % 997) + Math.floor(Math.random() * 997)) & 1;
203
+ var __canvasNoise = ((Date.now() & 0xFF) | 1);
138
204
  var origFill = CanvasRenderingContext2D.prototype.fillText;
139
205
  CanvasRenderingContext2D.prototype.fillText = __markNative(function fillText() {
140
206
  this.globalAlpha = 0.9995;
@@ -153,15 +219,39 @@ import{randomInt as r}from"node:crypto";import{spawn as t}from"node:child_proces
153
219
  HTMLCanvasElement.prototype.toDataURL = __markNative(function toDataURL() {
154
220
  var ctx = this.getContext('2d');
155
221
  if (ctx) {
156
- // Add 1px noise pixel in corner (invisible but changes hash)
157
- var imgData = ctx.getImageData(0, 0, 1, 1);
158
- if (imgData) imgData.data[0] ^= __canvasNoise;
159
- ctx.putImageData(imgData, 0, 0);
222
+ // Spread noise across canvas to break hash-based fingerprinting.
223
+ // Uses a deterministic pattern so it's consistent per page load
224
+ // but varies between sessions.
225
+ var w = this.width, h = this.height;
226
+ if (w > 0 && h > 0) {
227
+ var imgData = ctx.getImageData(0, 0, Math.min(w, 4), Math.min(h, 4));
228
+ if (imgData && imgData.data) {
229
+ for (var __i = 0; __i < imgData.data.length; __i += 4) {
230
+ imgData.data[__i] ^= (__canvasNoise + __i) & 0xFF;
231
+ }
232
+ ctx.putImageData(imgData, 0, 0);
233
+ }
234
+ }
160
235
  }
161
236
  return origToDataURL.apply(this, arguments);
162
237
  });
163
238
  } catch(_) {}
164
239
 
240
+ // ── AudioContext fingerprint noise ────────────────────
241
+ // Headless Chrome's AudioContext produces slightly different output.
242
+ // Subtle noise breaks audio-based fingerprinting.
243
+ try {
244
+ var __audioSeed = ((Date.now() & 0x1F) | 1);
245
+ var origGetChannelData = AudioBuffer.prototype.getChannelData;
246
+ AudioBuffer.prototype.getChannelData = __markNative(function getChannelData(channel) {
247
+ var data = origGetChannelData.call(this, channel);
248
+ for (var __i = 0; __i < data.length; __i += 64) {
249
+ data[__i] *= 0.99999;
250
+ }
251
+ return data;
252
+ });
253
+ } catch(_) {}
254
+
165
255
  // ── window outer dimensions ──────────────────────────
166
256
  // outerWidth/Height = 0 in headless — a well-known bot signal.
167
257
  // Mirror innerWidth/Height (set by --window-size flag) so the ratio is sane.
@@ -171,9 +261,15 @@ import{randomInt as r}from"node:crypto";import{spawn as t}from"node:child_proces
171
261
  } catch(_) {}
172
262
 
173
263
  // ── screen properties ─────────────────────────────────
264
+ // Headless Chrome often reports an 800x600 screen even when the viewport is
265
+ // 1920x1080. Keep screen metrics internally consistent with our launch flags.
174
266
  try {
175
- if (!screen.colorDepth) Object.defineProperty(screen, 'colorDepth', { get: () => 24, configurable: true });
176
- if (!screen.pixelDepth) Object.defineProperty(screen, 'pixelDepth', { get: () => 24, configurable: true });
267
+ Object.defineProperty(screen, 'width', { get: () => 1920, configurable: true });
268
+ Object.defineProperty(screen, 'height', { get: () => 1080, configurable: true });
269
+ Object.defineProperty(screen, 'availWidth', { get: () => 1920, configurable: true });
270
+ Object.defineProperty(screen, 'availHeight', { get: () => 1040, configurable: true });
271
+ Object.defineProperty(screen, 'colorDepth', { get: () => 24, configurable: true });
272
+ Object.defineProperty(screen, 'pixelDepth', { get: () => 24, configurable: true });
177
273
  } catch(_) {}
178
274
 
179
275
  // ── navigator.userAgentData (UA Client Hints) ─────────
@@ -246,12 +342,22 @@ import{randomInt as r}from"node:crypto";import{spawn as t}from"node:child_proces
246
342
  };
247
343
  } catch(_) {}
248
344
  })();
249
- `})])}function R(Z){if(!Z)return[];let X=[],K=0;while(K<Z.length&&X.length<10){let $=Z.indexOf("[",K);if($===-1)break;let Q=Z.indexOf("](",$);if(Q===-1)break;let H=Q+2,z=-1;for(let W=H;W<Z.length;W++){let J=Z[W];if(J===")"){z=W;break}if(/\s/.test(J))break}if(z!==-1){let W=Z.slice($+1,Q),J=Z.slice(H,z);if(/^https?:\/\//i.test(J)&&W){if(!X.some((Y)=>Y.url===J))X.push({title:W,url:J})}K=z+1}else K=$+1}return X}var L={postNav:800,postNavSlow:1200,postClick:300,postType:300,inputPoll:400,copyPoll:600,afterVerify:1500};async function w(Z,X,K={}){let{timeout:$=60000,onPoll:Q}=K,H=Date.now()+$,z=0;while(Date.now()<H){if(await new Promise((J)=>setTimeout(J,P(L.copyPoll))),Q)await Q(++z).catch(()=>null);if(await N(["eval",Z,`!!document.querySelector('${X}')`]).catch(()=>"false")==="true")return}throw Error(`Copy button ('${X}') did not appear within ${$}ms`)}function P(Z){let X=Z*0.4,K=r(-Math.floor(X),Math.floor(X)+1);return Math.max(50,Math.round(Z+K))}async function f(Z,X={}){let{timeout:K=20000,interval:$=600,stableRounds:Q=3,selector:H="document.body",minLength:z=0}=X,W=String.raw`
345
+ `})])}function h(Z){if(!Z)return[];let Q=[],K=0;while(K<Z.length&&Q.length<10){let $=Z.indexOf("[",K);if($===-1)break;let H=Z.indexOf("](",$);if(H===-1)break;let J=H+2,X=-1;for(let W=J;W<Z.length;W++){let U=Z[W];if(U===")"){X=W;break}if(/\s/.test(U))break}if(X!==-1){let W=Z.slice($+1,H),U=Z.slice(J,X);if(/^https?:\/\//i.test(U)&&W){if(!Q.some((Y)=>Y.url===U))Q.push({title:W,url:U})}K=X+1}else K=$+1}return Q}var E={postNav:800,postNavSlow:1200,postClick:300,postType:300,inputPoll:400,copyPoll:600,afterVerify:1500};async function v(Z,Q,K={}){let{timeout:$=60000,onPoll:H}=K;if(!H){let W=String.raw`
346
+ new Promise((resolve) => {
347
+ const _deadline = Date.now() + ${$};
348
+ function _poll() {
349
+ if (document.querySelector('${Q}')) { resolve(true); return; }
350
+ if (Date.now() < _deadline) { setTimeout(_poll, 150); }
351
+ else { resolve(false); }
352
+ }
353
+ _poll();
354
+ })
355
+ `;if(await G(["eval",Z,W],$+5000).catch(()=>"false")==="true")return;throw Error(`Copy button ('${Q}') did not appear within ${$}ms`)}let J=Date.now()+$,X=0;while(Date.now()<J){if(await G(["eval",Z,`!!document.querySelector('${Q}')`]).catch(()=>"false")==="true")return;await H(++X).catch(()=>null),await new Promise((U)=>setTimeout(U,M(E.copyPoll)))}throw Error(`Copy button ('${Q}') did not appear within ${$}ms`)}function M(Z){let Q=Z*0.2,K=KZ(-Math.floor(Q),Math.floor(Q)+1);return Math.max(50,Math.round(Z+K))}async function g(Z,Q={}){let{timeout:K=20000,interval:$=600,stableRounds:H=3,selector:J="document.body",minLength:X=0,isStreamingExpr:W="false"}=Q,U=String.raw`
250
356
  new Promise((resolve, reject) => {
251
357
  const _deadline = Date.now() + ${K};
252
358
  const _baseInterval = ${$};
253
- const _stableRounds = ${Q};
254
- const _minLength = ${z};
359
+ const _stableRounds = ${H};
360
+ const _minLength = ${X};
255
361
  let _lastLen = -1;
256
362
  let _stableCount = 0;
257
363
 
@@ -262,9 +368,13 @@ import{randomInt as r}from"node:crypto";import{spawn as t}from"node:child_proces
262
368
  function _poll() {
263
369
  try {
264
370
  // Re-query DOM each tick — element may not exist at eval start
265
- const el = ${H};
266
- const cur = el?.innerText?.length ?? 0;
267
- if (cur >= _minLength) {
371
+ const el = ${J};
372
+ const cur = el?.textContent?.length ?? 0;
373
+ const streaming = ${W};
374
+ if (streaming) {
375
+ if (cur !== _lastLen) _lastLen = cur;
376
+ _stableCount = 0;
377
+ } else if (cur >= _minLength) {
268
378
  if (cur === _lastLen) {
269
379
  _stableCount++;
270
380
  if (_stableCount >= _stableRounds) { resolve(cur); return; }
@@ -276,7 +386,7 @@ import{randomInt as r}from"node:crypto";import{spawn as t}from"node:child_proces
276
386
  if (Date.now() < _deadline) {
277
387
  setTimeout(_poll, _jitter(_baseInterval));
278
388
  } else {
279
- if (_lastLen >= _minLength) { resolve(_lastLen); }
389
+ if (_lastLen >= _minLength && !streaming) { resolve(_lastLen); }
280
390
  else { reject(new Error('Generation did not stabilise within ${K}ms')); }
281
391
  }
282
392
  } catch(e) { reject(e); }
@@ -284,7 +394,7 @@ import{randomInt as r}from"node:crypto";import{spawn as t}from"node:child_proces
284
394
 
285
395
  _poll();
286
396
  })
287
- `,J=await N(["eval",Z,W],K+1e4),Y=parseInt(J,10)||0;if(Y>=z)return Y;throw Error(`Generation did not stabilise within ${K}ms`)}async function h(Z,X,K=15000,$=500){let Q=String.raw`
397
+ `,Y=await G(["eval",Z,U],K+1e4),D=parseInt(Y,10)||0;if(D>=X)return D;throw Error(`Generation did not stabilise within ${K}ms`)}async function m(Z,Q,K=15000,$=500){let H=String.raw`
288
398
  new Promise((resolve) => {
289
399
  const _deadline = Date.now() + ${K};
290
400
  const _baseInterval = ${$};
@@ -295,7 +405,7 @@ import{randomInt as r}from"node:crypto";import{spawn as t}from"node:child_proces
295
405
 
296
406
  function _poll() {
297
407
  try {
298
- if (document.querySelector('${X}')) { resolve(true); return; }
408
+ if (document.querySelector('${Q}')) { resolve(true); return; }
299
409
  if (Date.now() < _deadline) { setTimeout(_poll, _jitter(_baseInterval)); }
300
410
  else { resolve(false); }
301
411
  } catch(_) { resolve(false); }
@@ -303,10 +413,10 @@ import{randomInt as r}from"node:crypto";import{spawn as t}from"node:child_proces
303
413
 
304
414
  _poll();
305
415
  })
306
- `;return await N(["eval",Z,Q],K+5000)==="true"}async function y(Z){let X=Z.indexOf("--stdin");if(X===-1)return Z;let K=await new Promise((Q)=>{let H="";process.stdin.setEncoding("utf8"),process.stdin.on("data",(z)=>H+=z),process.stdin.on("end",()=>Q(H.trim()))}),$=[...Z];return $[X]=K,$}function v(Z){let X=Z.includes("--short"),K=Z.filter((J)=>J!=="--short"),$=K.indexOf("--tab"),Q=$===-1?null:K[$+1];if($!==-1)K=K.filter((J,Y)=>Y!==$&&Y!==$+1);let H=K.indexOf("--locale"),z=H===-1?null:K[H+1];if(H!==-1)K=K.filter((J,Y)=>Y!==H&&Y!==H+1);return{query:K.join(" "),tabPrefix:Q,short:X,locale:z}}function g(Z,X){if(!Z.length||Z[0]==="--help")process.stderr.write(X),process.exit(1)}function m(Z,X,K=300){if(!X||Z.length<=K)return Z;let $=Z.slice(0,K),Q=$.lastIndexOf(" ");return Q>0?`${$.slice(0,Q)}…`:`${$}…`}function x(Z){process.stdout.write(`${JSON.stringify(Z,null,2)}
307
- `)}function M({engine:Z,mode:X="headless",clipboardEmpty:K=null,fallbackUsed:$=null,blockedBy:Q=null,verificationResult:H=null,inputReady:z=null,durationMs:W=null,lastStage:J=null,stages:Y=null}={}){return{engine:Z,mode:X,clipboardEmpty:K,fallbackUsed:$,blockedBy:Q,verificationResult:H,inputReady:z,durationMs:W,lastStage:J,stages:Y}}function b(Z,X=null){if(X){let K=JSON.stringify({_envelope:X,error:Z.message});process.stdout.write(`${K}
416
+ `;return await G(["eval",Z,H],K+5000)==="true"}async function b(Z){let Q=Z.indexOf("--stdin");if(Q===-1)return Z;let K=await new Promise((H)=>{let J="";process.stdin.setEncoding("utf8"),process.stdin.on("data",(X)=>J+=X),process.stdin.on("end",()=>H(J.trim()))}),$=[...Z];return $[Q]=K,$}function x(Z){let Q=Z.includes("--short"),K=Z.filter((U)=>U!=="--short"),$=K.indexOf("--tab"),H=$===-1?null:K[$+1];if($!==-1)K=K.filter((U,Y)=>Y!==$&&Y!==$+1);let J=K.indexOf("--locale"),X=J===-1?null:K[J+1];if(J!==-1)K=K.filter((U,Y)=>Y!==J&&Y!==J+1);return{query:K.join(" "),tabPrefix:H,short:Q,locale:X}}function u(Z,Q){if(!Z.length||Z[0]==="--help")process.stderr.write(Q),process.exit(1)}function p(Z,Q,K=300){if(!Q||Z.length<=K)return Z;let $=Z.slice(0,K),H=$.lastIndexOf(" ");return H>0?`${$.slice(0,H)}…`:`${$}…`}function l(Z){process.stdout.write(`${JSON.stringify(Z,null,2)}
417
+ `)}function P({engine:Z,mode:Q="headless",clipboardEmpty:K=null,fallbackUsed:$=null,blockedBy:H=null,verificationResult:J=null,inputReady:X=null,durationMs:W=null,lastStage:U=null,stages:Y=null}={}){return{engine:Z,mode:Q,clipboardEmpty:K,fallbackUsed:$,blockedBy:H,verificationResult:J,inputReady:X,durationMs:W,lastStage:U,stages:Y}}function d(Z,Q=null){if(Q){let K=JSON.stringify({_envelope:Q,error:Z.message});process.stdout.write(`${K}
308
418
  `)}process.stderr.write(`Error: ${Z.message}
309
- `),process.exit(1)}import{randomInt as HZ}from"node:crypto";import{existsSync as WZ,readFileSync as YZ}from"node:fs";import JZ from"node:http";var NZ=`
419
+ `),process.exit(1)}import{randomInt as zZ}from"node:crypto";import{existsSync as _Z,readFileSync as NZ}from"node:fs";import qZ from"node:http";var BZ=`
310
420
  (function() {
311
421
  // Google consent page (consent.google.com)
312
422
  var g = document.querySelector('#L2AGLb, button[jsname="b3VHJd"], .tHlp8d');
@@ -323,7 +433,7 @@ import{randomInt as r}from"node:crypto";import{spawn as t}from"node:child_proces
323
433
 
324
434
  return null;
325
435
  })()
326
- `,UZ=`
436
+ `,VZ=`
327
437
  (function() {
328
438
  var url = document.location.href;
329
439
 
@@ -354,12 +464,24 @@ import{randomInt as r}from"node:crypto";import{spawn as t}from"node:child_proces
354
464
 
355
465
  // --- Cloudflare Turnstile widget inside closed shadow DOM (Copilot, etc.) ---
356
466
  // The iframe is not queryable from main document, but the host container
357
- // (#cf-turnstile) and the hidden response input are.
358
- var cfTurnstileHost = document.querySelector('#cf-turnstile, [id^="cf-chl-widget-"]');
467
+ // (#cf-turnstile) and the hidden response input are. When only the
468
+ // hidden response input matches (no #cf-turnstile host and no visible
469
+ // iframe), the actual challenge widget is rendered inside a closed
470
+ // shadow DOM and cannot be auto-clicked. Return a sentinel so callers
471
+ // know to surface this as needs-human verification instead of wasting
472
+ // time on a doomed waitForSelector.
473
+ var cfTurnstileHost = document.querySelector('#cf-turnstile');
359
474
  if (cfTurnstileHost) {
360
475
  var r2 = cfTurnstileHost.getBoundingClientRect();
361
476
  return JSON.stringify({t:'xy',x:r2.left+r2.width/2,y:r2.top+r2.height/2});
362
477
  }
478
+ // Hidden cf-chl-widget-*_response input present but no visible host:
479
+ // the widget is in closed shadow DOM. Signal this so handleVerification
480
+ // can return 'needs-human' rather than 'clear'.
481
+ var cfResponseInput = document.querySelector('input[name="cf-turnstile-response"], [id^="cf-chl-widget-"][id$="_response"]');
482
+ if (cfResponseInput && cfResponseInput.value === '') {
483
+ return 'cf-closed-shadow-dom';
484
+ }
363
485
 
364
486
  // --- Cloudflare challenge page ---
365
487
  var cfCheckbox = document.querySelector('#cf-stage input[type="checkbox"], .ctp-checkbox-container input');
@@ -374,15 +496,28 @@ import{randomInt as r}from"node:crypto";import{spawn as t}from"node:child_proces
374
496
  }
375
497
 
376
498
  // --- Generic verify/continue/proceed buttons (catch-all) ---
377
- // IMPORTANT: exclude sign-in / OAuth buttons (e.g. "Continue with Google")
499
+ // IMPORTANT: exclude sign-in / OAuth buttons (e.g. "Continue with Google",
500
+ // "Continue with email", "Login or sign up for free"). These appear on
501
+ // many sites (Perplexity, ChatGPT, etc.) when the user isn't logged in,
502
+ // and clicking them triggers a sign-in flow that takes us to a login
503
+ // wall — a much worse outcome than the original search failure we were
504
+ // trying to recover from. The exclusion list must cover both OAuth
505
+ // providers AND generic "sign in / log in / with email" patterns.
378
506
  var btns = Array.from(document.querySelectorAll('button, input[type=submit], a[role=button]'));
379
507
  var verify = btns.find(b => {
380
508
  var t = (b.innerText?.trim() || b.value || '').toLowerCase();
381
- var isVerifyLike = (t.includes('verify') || t.includes('human') || t.includes('robot') || t.includes('continue') || t.includes('proceed')) &&
509
+ var isVerifyLike = (t === 'continue' || t === 'proceed' || t === 'next' ||
510
+ t.startsWith('verify ') || t.startsWith('human ') || t === 'i am human' || t.includes('robot check')) &&
382
511
  !t.includes('verified') && !document.querySelector('iframe[src*="recaptcha"]');
383
512
  if (!isVerifyLike) return false;
384
513
  // Exclude OAuth / sign-in buttons to prevent accidental login flows
385
- var isSignIn = /sign.in|log.in|google|microsoft|apple|facebook|github|auth/i.test(t);
514
+ // covers "Continue with Google", "Continue with Apple", "Continue
515
+ // with email", "Login or sign up", "Log in", "Sign in", "Sign up",
516
+ // "Single sign-on", and the visible panel "Login or sign up for free"
517
+ // text. The previous list missed "email" and "sso" which let the
518
+ // auto-click land on the email/SSO sign-in buttons on Perplexity's
519
+ // anonymous-mode homepage, navigating us into a login flow.
520
+ var isSignIn = new RegExp("sign.?in|log.?in|sign.?up|with\\s+(google|apple|email|github|facebook|microsoft|sso)|sso|auth", "i").test(t);
386
521
  return !isSignIn;
387
522
  });
388
523
  if (verify) { verify.setAttribute('data-gs-verify','1'); return JSON.stringify({t:'sel',s:'[data-gs-verify="1"]',txt:verify.innerText?.trim()||verify.value}); }
@@ -393,7 +528,7 @@ import{randomInt as r}from"node:crypto";import{spawn as t}from"node:child_proces
393
528
 
394
529
  return null;
395
530
  })()
396
- `,DZ=`
531
+ `,LZ=`
397
532
  (function() {
398
533
  var url = document.location.href;
399
534
  var isVerifyPage = url.includes('/sorry/') ||
@@ -427,18 +562,20 @@ import{randomInt as r}from"node:crypto";import{spawn as t}from"node:child_proces
427
562
 
428
563
  return 'still-verifying';
429
564
  })()
430
- `;async function C(Z,X){let K=await X(["eval",Z,NZ]).catch(()=>null);if(K&&K!=="null")await new Promise(($)=>setTimeout($,1500))}function D(Z,X){return HZ(Z*1000,X*1000)/1000}async function GZ(Z,X){if(!globalThis.WebSocket)return;let K=process.env.CDP_PROFILE_DIR;if(!K)return;let $=`${K.replaceAll("\\","/")}/DevToolsActivePort`;if(!WZ($))return;let Q=YZ($,"utf8").trim().split(`
431
- `)[0],H=await new Promise((J,Y)=>{let G=JZ.get(`http://localhost:${Q}/json/version`,(_)=>{let O="";_.on("data",(V)=>O+=V),_.on("end",()=>{try{J(JSON.parse(O))}catch{Y(Error("bad JSON"))}})});G.on("error",Y),G.setTimeout(1000,()=>{G.destroy(),Y(Error("timeout"))})}),z=new globalThis.WebSocket(H.webSocketDebuggerUrl),W=0;await new Promise((J)=>{z.onopen=async()=>{let Y=(O,V)=>new Promise((A)=>{let U=++W,E=(q)=>{if(JSON.parse(q.data).id===U)z.removeEventListener("message",E),A()};z.addEventListener("message",E),z.send(JSON.stringify({id:U,method:O,params:V}))}),G=Z+D(-2,2),_=X+D(-2,2);await Y("Input.dispatchMouseEvent",{type:"mouseMoved",x:G,y:_,button:"none"}),await new Promise((O)=>setTimeout(O,D(80,160))),await Y("Input.dispatchMouseEvent",{type:"mousePressed",x:G,y:_,button:"left",clickCount:1}),await new Promise((O)=>setTimeout(O,D(30,80))),await Y("Input.dispatchMouseEvent",{type:"mouseReleased",x:G+D(-1,1),y:_+D(-1,1),button:"left",clickCount:1}),setTimeout(()=>{z.close(),J()},200)},z.onerror=()=>J(),setTimeout(J,3000)})}async function p(Z,X,K,$){let Q=Number.parseFloat(K),H=Number.parseFloat($);if(Number.isNaN(Q)||Number.isNaN(H))throw Error(`humanClickXY: invalid coordinates (${K}, ${$})`);let z={button:"left",clickCount:1,modifiers:0},W=Q+D(-3,3),J=H+D(-3,3);await X(["evalraw",Z,"Input.dispatchMouseEvent",JSON.stringify({...z,type:"mouseMoved",x:W,y:J})]),await new Promise((V)=>setTimeout(V,D(80,180)));let Y=Q+D(-2,2),G=H+D(-2,2);await X(["evalraw",Z,"Input.dispatchMouseEvent",JSON.stringify({...z,type:"mousePressed",x:Y,y:G})]),await new Promise((V)=>setTimeout(V,D(30,90)));let _=Y+D(-1,1),O=G+D(-1,1);return await X(["evalraw",Z,"Input.dispatchMouseEvent",JSON.stringify({...z,type:"mouseReleased",x:_,y:O})]),await GZ(Q,H).catch(()=>{}),await new Promise((V)=>setTimeout(V,D(100,300))),`human-clicked at (${Q.toFixed(0)}, ${H.toFixed(0)})`}async function OZ(Z,X,K){let $=await X(["eval",Z,`(function() {
565
+ `;async function S(Z,Q){let K=await Q(["eval",Z,BZ]).catch(()=>null);if(K&&K!=="null")await new Promise(($)=>setTimeout($,1500))}function q(Z,Q){return zZ(Z*1000,Q*1000)/1000}async function jZ(Z,Q){if(!globalThis.WebSocket)return;let K=process.env.CDP_PROFILE_DIR;if(!K)return;let $=`${K.replaceAll("\\","/")}/DevToolsActivePort`;if(!_Z($))return;let H=NZ($,"utf8").trim().split(`
566
+ `)[0],J=await new Promise((U,Y)=>{let D=qZ.get(`http://localhost:${H}/json/version`,(z)=>{let _="";z.on("data",(N)=>_+=N),z.on("end",()=>{try{U(JSON.parse(_))}catch{Y(Error("bad JSON"))}})});D.on("error",Y),D.setTimeout(1000,()=>{D.destroy(),Y(Error("timeout"))})}),X=new globalThis.WebSocket(J.webSocketDebuggerUrl),W=0;await new Promise((U)=>{X.onopen=async()=>{let Y=(_,N)=>new Promise((j)=>{let O=++W,V=(B)=>{if(JSON.parse(B.data).id===O)X.removeEventListener("message",V),j()};X.addEventListener("message",V),X.send(JSON.stringify({id:O,method:_,params:N}))}),D=Z+q(-2,2),z=Q+q(-2,2);await Y("Input.dispatchMouseEvent",{type:"mouseMoved",x:D,y:z,button:"none"}),await new Promise((_)=>setTimeout(_,q(80,160))),await Y("Input.dispatchMouseEvent",{type:"mousePressed",x:D,y:z,button:"left",clickCount:1}),await new Promise((_)=>setTimeout(_,q(30,80))),await Y("Input.dispatchMouseEvent",{type:"mouseReleased",x:D+q(-1,1),y:z+q(-1,1),button:"left",clickCount:1}),setTimeout(()=>{X.close(),U()},200)},X.onerror=()=>U(),setTimeout(U,3000)})}async function c(Z,Q,K,$){let H=Number.parseFloat(K),J=Number.parseFloat($);if(Number.isNaN(H)||Number.isNaN(J))throw Error(`humanClickXY: invalid coordinates (${K}, ${$})`);let X={button:"left",clickCount:1,modifiers:0},W=H+q(-3,3),U=J+q(-3,3);await Q(["evalraw",Z,"Input.dispatchMouseEvent",JSON.stringify({...X,type:"mouseMoved",x:W,y:U})]),await new Promise((N)=>setTimeout(N,q(80,180)));let Y=H+q(-2,2),D=J+q(-2,2);await Q(["evalraw",Z,"Input.dispatchMouseEvent",JSON.stringify({...X,type:"mousePressed",x:Y,y:D})]),await new Promise((N)=>setTimeout(N,q(30,90)));let z=Y+q(-1,1),_=D+q(-1,1);return await Q(["evalraw",Z,"Input.dispatchMouseEvent",JSON.stringify({...X,type:"mouseReleased",x:z,y:_})]),await jZ(H,J).catch(()=>{}),await new Promise((N)=>setTimeout(N,q(100,300))),`human-clicked at (${H.toFixed(0)}, ${J.toFixed(0)})`}async function EZ(Z,Q,K){let $=await Q(["eval",Z,`(function() {
432
567
  var el = document.querySelector('${K.replace(/\\/g,"\\\\").replace(/'/g,"\\'")}');
433
568
  if (!el) return 'null';
434
569
  var r = el.getBoundingClientRect();
435
570
  return JSON.stringify({x: r.left + r.width / 2, y: r.top + r.height / 2, w: r.width, h: r.height});
436
- })()`]).catch(()=>"null");if(!$||$==="null")return null;let Q=JSON.parse($);if(Q.w===0||Q.h===0||Q.x===0&&Q.y===0)return null;let{x:H,y:z}=Q;return p(Z,X,H,z)}async function u(Z,X,K){if(!K||K==="null"||K==="cleared"||K==="still-verifying")return!1;try{let $=JSON.parse(K);if($.t==="sel"&&$.s)return process.stderr.write(`[greedysearch] Human-clicking "${$.txt}" via CDP...
437
- `),await OZ(Z,X,$.s)!==null;if($.t==="xy"){if(!$.x&&!$.y)return!1;return process.stderr.write(`[greedysearch] Human-clicking at (${$.x.toFixed(0)}, ${$.y.toFixed(0)})...
438
- `),await p(Z,X,$.x,$.y),!0}}catch{}return!1}async function j(Z,X){let K=await X(["eval",Z,UZ]).catch(()=>null);return K&&K!=="null"?K:null}async function S(Z,X,K=30000){let $=await j(Z,X);if(!$)return"clear";if($==="sorry-page"){process.stderr.write(`[greedysearch] Google CAPTCHA detected please solve it in the browser window (waiting up to ${Math.floor(K/1000)}s)...
439
- `);let H=Date.now()+K;while(Date.now()<H)if(await new Promise((W)=>setTimeout(W,2000)),!(await X(["eval",Z,"document.location.href"]).catch(()=>"")).includes("/sorry/"))return"cleared-by-user";return"needs-human"}if(await u(Z,X,$)){await new Promise((z)=>setTimeout(z,2000));let H=Date.now()+K;while(Date.now()<H){let z=await X(["eval",Z,DZ]).catch(()=>null);if(z==="cleared"||!z||z==="null")return process.stderr.write(`[greedysearch] Verification cleared.
440
- `),"clicked";if(z!=="still-verifying")await u(Z,X,z),await new Promise((W)=>setTimeout(W,2000));else await new Promise((W)=>setTimeout(W,1500))}return process.stderr.write(`[greedysearch] Verification may require manual intervention.
441
- `),"needs-human"}return"clear"}var d={perplexity:{input:"#ask-input",copyButton:null,sourceItem:"[data-pplx-citation-url]",sourceLink:"a",consent:"#onetrust-accept-btn-handler"},bing:{input:"#userInput",copyButton:'button[data-testid="copy-ai-message-button"]',sourceLink:'a[href^="http"][target="_blank"]',sourceExclude:"copilot.microsoft.com",consent:"#onetrust-accept-btn-handler"},google:{answerContainer:".pWvJNd",sourceLink:'a[href^="http"]',sourceExclude:["google.","gstatic","googleapis"],sourceHeadingParent:"[data-snhf]",consent:'#L2AGLb, button[jsname="b3VHJd"], .tHlp8d'},gemini:{input:"rich-textarea .ql-editor",copyButton:'button:has(mat-icon[data-mat-icon-name="copy"])',sendButton:'button:has(mat-icon[data-mat-icon-name="arrow_upward"]), [data-test-id="send-button"], .send-button',sourcesSidebarButton:"button.legacy-sources-sidebar-button",sourcesExclude:["gemini.google","gstatic","google.com/search"],citationButtonPattern:'button[aria-label*="citation from"]',citationNameRegex:/from\s{1,20}([^.]{1,200})\.\s/}};var B=d.bing,T="__bingClipboard";async function l(Z){return await N(["eval",Z,`(() => {
571
+ })()`]).catch(()=>"null");if(!$||$==="null")return null;let H=JSON.parse($);if(H.w===0||H.h===0||H.x===0&&H.y===0)return null;let{x:J,y:X}=H;return c(Z,Q,J,X)}function i(Z,Q,K){if(!K||K==="null"||K==="cleared"||K==="still-verifying"||K==="cf-closed-shadow-dom")return Promise.resolve("no-challenge");try{let $=JSON.parse(K);if($.t==="sel"&&$.s)return process.stderr.write(`[greedysearch] Human-clicking "${$.txt}" via CDP...
572
+ `),EZ(Z,Q,$.s).then((H)=>H!==null?"clicked":"cant-click");if($.t==="xy"){if(!$.x&&!$.y)return Promise.resolve("cant-click");return process.stderr.write(`[greedysearch] Human-clicking at (${$.x.toFixed(0)}, ${$.y.toFixed(0)})...
573
+ `),c(Z,Q,$.x,$.y).then(()=>"clicked")}}catch{}return Promise.resolve("no-challenge")}async function A(Z,Q){let K=await Q(["eval",Z,VZ]).catch(()=>null);if(K==="cf-closed-shadow-dom"){let $=await AZ(Z,Q).catch(()=>null);if($)return $;return K}if(K&&K!=="null")return K;return null}async function AZ(Z,Q){if(typeof Q!=="function")return null;await Q(["evalraw",Z,"DOM.enable","{}"]).catch(()=>{});let K=await Q(["evalraw",Z,"DOM.getDocument",JSON.stringify({depth:-1,pierce:!0})]).catch(()=>null);if(!K)return null;let $;try{$=JSON.parse(K)}catch{return null}if($.error||!$.root)return null;let H=$.root;return await o(H,Z,Q)}async function o(Z,Q,K){if(!Z)return null;let $=[];if(Z.shadowRoots&&Z.shadowRoots.length>0)for(let H of Z.shadowRoots)$.push(H);if(Z.children)for(let H of Z.children)$.push(H);for(let H of $){if(H.nodeName==="IFRAME"){let X=H.attributes||[],W=X.indexOf("src"),U=W>=0?X[W+1]:"";if(U&&/challenges\.cloudflare\.com|turnstile/i.test(U)&&H.backendNodeId){let Y=await K(["evalraw",Q,"DOM.getBoxModel",JSON.stringify({backendNodeId:H.backendNodeId})]).catch(()=>null);if(!Y)continue;let D;try{D=JSON.parse(Y)}catch{continue}let z=D?.model?.content||D?.result?.model?.content;if(!z||z.length<8)continue;let _=z[0],N=z[1],j=z[4],O=z[5],V=j-_,B=O-N;if(V<50||B<20)continue;let C=_+V*0.25,I=N+B*0.5;return process.stderr.write(`[greedysearch] Found CF iframe via CDP pierce at (${_.toFixed(0)}, ${N.toFixed(0)}) ${V.toFixed(0)}x${B.toFixed(0)}, clicking checkbox at (${C.toFixed(0)}, ${I.toFixed(0)})
574
+ `),JSON.stringify({t:"xy",x:C,y:I})}}let J=await o(H,Q,K);if(J)return J}return null}async function T(Z,Q,K=30000){let $=await A(Z,Q);if(!$)return"clear";if($==="sorry-page"){process.stderr.write(`[greedysearch] Google CAPTCHA detected — please solve it in the browser window (waiting up to ${Math.floor(K/1000)}s)...
575
+ `);let J=Date.now()+K;while(Date.now()<J)if(await new Promise((W)=>setTimeout(W,2000)),!(await Q(["eval",Z,"document.location.href"]).catch(()=>"")).includes("/sorry/"))return"cleared-by-user";return"needs-human"}let H=await i(Z,Q,$);if(H==="clicked"){await new Promise((X)=>setTimeout(X,2000));let J=Date.now()+K;while(Date.now()<J){let X=await Q(["eval",Z,LZ]).catch(()=>null);if(X==="cleared"||!X||X==="null")return process.stderr.write(`[greedysearch] Verification cleared.
576
+ `),"clicked";if(X!=="still-verifying")await i(Z,Q,X),await new Promise((W)=>setTimeout(W,2000));else await new Promise((W)=>setTimeout(W,1500))}return process.stderr.write(`[greedysearch] Verification may require manual intervention.
577
+ `),"needs-human"}if(H==="cant-click")return process.stderr.write(`[greedysearch] Verification challenge detected but cannot be auto-clicked — please solve it manually in the visible browser window.
578
+ `),"needs-human";return"clear"}var n={perplexity:{input:"#ask-input",copyButton:null,sourceItem:"[data-pplx-citation-url]",sourceLink:"a",consent:"#onetrust-accept-btn-handler"},bing:{input:"#userInput",copyButton:'button[data-testid="copy-ai-message-button"]',sourceLink:'a[href^="http"][target="_blank"]',sourceExclude:"copilot.microsoft.com",consent:"#onetrust-accept-btn-handler"},google:{answerContainer:".pWvJNd",sourceLink:'a[href^="http"]',sourceExclude:["google.","gstatic","googleapis"],sourceHeadingParent:"[data-snhf]",consent:'#L2AGLb, button[jsname="b3VHJd"], .tHlp8d'},gemini:{input:"rich-textarea .ql-editor",copyButton:'button:has(mat-icon[data-mat-icon-name="copy"])',sendButton:'button:has(mat-icon[data-mat-icon-name="arrow_upward"]), [data-test-id="send-button"], .send-button',sourcesSidebarButton:"button.legacy-sources-sidebar-button",sourcesExclude:["gemini.google","gstatic","google.com/search"],citationButtonPattern:'button[aria-label*="citation from"]',citationNameRegex:/from\s{1,20}([^.]{1,200})\.\s/}};var L=n.bing,F="__bingClipboard";async function s(Z){return await G(["eval",Z,`(() => {
442
579
  if (document.querySelector('#userInput')) return false;
443
580
  const links = Array.from(document.querySelectorAll('a[href], button'));
444
581
  const hasOAuth = links.some(el => {
@@ -448,10 +585,10 @@ import{randomInt as r}from"node:crypto";import{spawn as t}from"node:child_proces
448
585
  || h.includes('accounts.google.com');
449
586
  });
450
587
  return hasOAuth;
451
- })()`]).catch(()=>"false")==="true"}async function _Z(Z,X,K=""){if(process.env.GREEDY_SEARCH_HEADLESS==="1"){if(await j(Z,N))throw console.error("[bing] Verification challenge detected — fast-failing to visible retry"),X.blockedBy="verification",Error("Verification challenge detected — headless blocked")}await w(Z,B.copyButton,{timeout:2000}).catch(()=>null),await new Promise((z)=>setTimeout(z,800));let $=await i(Z,5000),Q=!$;if(!$)console.error("[bing] Clipboard empty, retrying copy/poll..."),$=await i(Z,8000),Q=!$;if(!$){if($=await VZ(Z,K),$)X.fallbackUsed="visibleDom"}if(!$){if($=await qZ(Z,K),$)X.fallbackUsed="accessibilityTree"}if(!$){if($=(await EZ(Z,X)).answer,$)X.fallbackUsed="iframeDom"}if(!$)throw Error("Clipboard interceptor returned empty text");X.clipboardEmpty=Q;let H=R($);return{answer:$.trim(),sources:H}}async function i(Z,X){await N(["eval",Z,`(() => {
452
- window.${T} = '';
453
- const buttons = document.querySelectorAll('${B.copyButton}');
454
- buttons[buttons.length - 1]?.click();
455
- })()`]);let K=Date.now()+X;while(Date.now()<K){let $=await N(["eval",Z,`window.${T} || ''`]).catch(()=>"");if($)return $;await new Promise((Q)=>setTimeout(Q,300))}return""}async function VZ(Z,X=""){try{let K=await N(["eval",Z,"document.body?.innerText || ''"]).catch(()=>""),$="";if(K&&K.includes("Copilot said")){let H=K.split(/Copilot said\s*/i).pop()||"";$=n(s(H))}if(!$){let Q=await N(["eval",Z,"JSON.stringify(Array.from(document.querySelectorAll('article')).map(a => a.innerText || '').filter(Boolean))"]).catch(()=>"[]"),H=JSON.parse(Q||"[]");$=o(H,X)}if($.length<20)return"";return console.error(`[bing] Visible DOM extraction succeeded (${$.length} chars)`),$}catch(K){return console.error(`[bing] Visible DOM extraction failed: ${K.message}`),""}}async function qZ(Z,X=""){try{let K=await N(["snap",Z]).catch(()=>"");if(!K||await j(Z,N))return"";let $=[];for(let H of K.split(`
456
- `)){let z=H.trimStart();if(!z.toLowerCase().startsWith("[article]"))continue;let W=z.slice(9).trimStart();if(W)$.push(W)}if($.length===0)return"";let Q=o($,X);if(Q.length<50)return"";return console.error(`[bing] Accessibility extraction succeeded (${Q.length} chars)`),Q}catch(K){return console.error(`[bing] Accessibility extraction failed: ${K.message}`),""}}function o(Z,X=""){let K=c(X);return Z.map((Q)=>n(Q)).filter((Q)=>Q.length>=50).filter((Q)=>{if(!K)return!0;return!c(Q).includes(K)||Q.length>X.length*3}).at(-1)||""}function c(Z=""){return String(Z).toLocaleLowerCase().replace(/\s+/g," ").trim()}var BZ=["Good response","Bad response","Share message","Copy message","Read aloud","Regenerate","Edit in a page","Message Copilot","Smart"];function s(Z){let X=Z.length;for(let K of BZ){let $=0;while($<Z.length){let Q=Z.indexOf(K,$);if(Q===-1)break;let H=Q>0?Z[Q-1]:"",z=!H||/\s/.test(H),W=Z[Q+K.length]||"",J=!W||!/\w/.test(W);if(z&&J){if(Q<X)X=Q;break}$=Q+K.length}}return X<Z.length?Z.slice(0,X):Z}function n(Z=""){return s(String(Z).replace(/\s+/g," ")).trim()}async function EZ(Z,X){try{if(await N(["eval",Z,`!!document.querySelector('${B.copyButton}')`]).catch(()=>"false")==="true")return{answer:""};if(await j(Z,N))return console.error("[bing] Verification challenge detected — content blocked in headless"),X.blockedBy="verification",{answer:""};console.error("[bing] Copy button hidden, no Cloudflare — trying DOM extraction...");let $=await N(["evalraw",Z,"Target.getTargets","{}"]),z=(JSON.parse($).targetInfos||[]).find((Y)=>Y.type==="iframe"&&Y.url.includes("copilot.fun"));if(!z)return console.error("[bing] No copilot.fun iframe target found"),{answer:""};let W=z.targetId.slice(0,8),J=await N(["eval",W,"(()=>{const iframe=document.querySelector('iframe'); if(!iframe) return''; try{const doc=iframe.contentDocument||iframe.contentWindow.document; return doc?.body?.innerText?.trim()||''}catch(e){return''}})()"]).catch(()=>"");if(J)return console.error(`[bing] DOM extraction succeeded (${J.length} chars)`),{answer:J};console.error("[bing] DOM extraction returned empty — falling through to visible retry")}catch(K){console.error(`[bing] DOM extraction failed: ${K.message}`)}return{answer:""}}var LZ=`Usage: node extractors/bing-copilot.mjs "<query>" [--tab <prefix>]
457
- `;async function jZ(){let Z=await y(process.argv.slice(2));g(Z,LZ);let{query:X,tabPrefix:K,short:$}=v(Z),Q=Date.now(),z={engine:"bing",mode:process.env.GREEDY_SEARCH_VISIBLE==="1"?"visible":"headless",clipboardEmpty:null,fallbackUsed:null,blockedBy:null,verificationResult:null,inputReady:null};try{if(!K)await N(["list"]);let W=await F(K),J=await N(["eval",W,"document.location.href"]).catch(()=>""),Y=!1;try{let U=new URL(J).hostname.toLowerCase();Y=U==="copilot.microsoft.com"||U.endsWith(".copilot.microsoft.com")}catch{}if(!Y)await N(["nav",W,"https://copilot.microsoft.com/"],20000),await new Promise((U)=>setTimeout(U,600));await C(W,N);let G=await S(W,N,1e4);if(z.verificationResult=G,G==="needs-human")throw Error("Copilot verification required — please solve it manually in the browser window");if(G==="clicked"){await new Promise((q)=>setTimeout(q,L.afterVerify));let U=await N(["eval",W,"document.location.href"]).catch(()=>""),E=!1;try{let q=new URL(U).hostname.toLowerCase();E=q==="copilot.microsoft.com"||q.endsWith(".copilot.microsoft.com")}catch{}if(!E)await N(["nav",W,"https://copilot.microsoft.com/"],20000),await new Promise((q)=>setTimeout(q,600)),await C(W,N)}if(await l(W))throw Error("Copilot requires sign-in — please sign in with Microsoft, Apple, or Google in the visible browser window. Once signed in, cookies persist for future runs.");let _=await h(W,B.input,15000,500);if(z.inputReady=_,await new Promise((U)=>setTimeout(U,P(300))),!_){if(await l(W))throw Error("Copilot requires sign-in — please sign in with Microsoft, Apple, or Google in the visible browser window. Once signed in, cookies persist for future runs.");throw Error("Copilot input not found — verification may have failed or page is in unexpected state")}await I(W,T),await N(["click",W,B.input]),await new Promise((U)=>setTimeout(U,L.postClick)),await N(["type",W,X]),await new Promise((U)=>setTimeout(U,L.postType)),await N(["eval",W,`document.querySelector('${B.input}')?.dispatchEvent(new KeyboardEvent('keydown',{key:'Enter',bubbles:true,keyCode:13})), 'ok'`]),setTimeout(()=>{S(W,N,1e4).then((U)=>{if(U==="clicked")console.error("[bing] Post-submit verification clicked"),z.verificationResult="post-submit-clicked"}).catch(()=>{})},2000),await f(W,{timeout:$?25000:60000,minLength:50});let{answer:O,sources:V}=await _Z(W,z,X);if(!O)throw Error("No answer extracted — Copilot may not have responded");let A=await N(["eval",W,"document.location.href"]).catch(()=>"");z.durationMs=Date.now()-Q,x({query:X,url:A,answer:m(O,$),sources:V,_envelope:M(z)})}catch(W){z.durationMs=Date.now()-Q,b(W,M(z))}}jZ();
588
+ })()`]).catch(()=>"false")==="true"}async function MZ(Z,Q,K=""){await v(Z,L.copyButton,{timeout:2000}).catch(()=>null),await new Promise((X)=>setTimeout(X,800));let $=await a(Z,5000),H=!$;if(!$)console.error("[bing] Clipboard empty, retrying copy/poll..."),$=await a(Z,8000),H=!$;if(!$){if($=await PZ(Z,K),$)Q.fallbackUsed="visibleDom"}if(!$){if($=await SZ(Z,K),$)Q.fallbackUsed="accessibilityTree"}if(!$){if($=(await FZ(Z,Q)).answer,$)Q.fallbackUsed="iframeDom"}if(!$)throw Error("Clipboard interceptor returned empty text");Q.clipboardEmpty=H;let J=h($);return{answer:$.trim(),sources:J}}async function a(Z,Q){let K=`(() => {
589
+ window.${F} = '';
590
+ const buttons = document.querySelectorAll('${L.copyButton}');
591
+ buttons[buttons.length - 1]?.click();
592
+ })()`;return y(Z,K,F,{timeoutMs:Q,retryClick:Q*2})}async function PZ(Z,Q=""){try{let K=await G(["eval",Z,"document.body?.innerText || ''"]).catch(()=>""),$="";if(K&&K.includes("Copilot said")){let J=K.split(/Copilot said\s*/i).pop()||"";$=ZZ(e(J))}if(!$){let H=await G(["eval",Z,"JSON.stringify(Array.from(document.querySelectorAll('article')).map(a => a.innerText || '').filter(Boolean))"]).catch(()=>"[]"),J=JSON.parse(H||"[]");$=t(J,Q)}if($.length<20)return"";return console.error(`[bing] Visible DOM extraction succeeded (${$.length} chars)`),$}catch(K){return console.error(`[bing] Visible DOM extraction failed: ${K.message}`),""}}async function SZ(Z,Q=""){try{let K=await G(["snap",Z]).catch(()=>"");if(!K||await A(Z,G))return"";let $=[];for(let J of K.split(`
593
+ `)){let X=J.trimStart();if(!X.toLowerCase().startsWith("[article]"))continue;let W=X.slice(9).trimStart();if(W)$.push(W)}if($.length===0)return"";let H=t($,Q);if(H.length<50)return"";return console.error(`[bing] Accessibility extraction succeeded (${H.length} chars)`),H}catch(K){return console.error(`[bing] Accessibility extraction failed: ${K.message}`),""}}function t(Z,Q=""){let K=r(Q);return Z.map((H)=>ZZ(H)).filter((H)=>H.length>=50).filter((H)=>{if(!K)return!0;return!r(H).includes(K)||H.length>Q.length*3}).at(-1)||""}function r(Z=""){return String(Z).toLocaleLowerCase().replace(/\s+/g," ").trim()}var TZ=["Good response","Bad response","Share message","Copy message","Read aloud","Regenerate","Edit in a page","Message Copilot","Smart"];function e(Z){let Q=Z.length;for(let K of TZ){let $=0;while($<Z.length){let H=Z.indexOf(K,$);if(H===-1)break;let J=H>0?Z[H-1]:"",X=!J||/\s/.test(J),W=Z[H+K.length]||"",U=!W||!/\w/.test(W);if(X&&U){if(H<Q)Q=H;break}$=H+K.length}}return Q<Z.length?Z.slice(0,Q):Z}function ZZ(Z=""){return e(String(Z).replace(/\s+/g," ")).trim()}async function FZ(Z,Q){try{if(await G(["eval",Z,`!!document.querySelector('${L.copyButton}')`]).catch(()=>"false")==="true")return{answer:""};if(await A(Z,G))return console.error("[bing] Verification challenge detected — content blocked in headless"),Q.blockedBy="verification",{answer:""};console.error("[bing] Copy button hidden, no Cloudflare — trying DOM extraction...");let $=await G(["evalraw",Z,"Target.getTargets","{}"]),X=(JSON.parse($).targetInfos||[]).find((Y)=>Y.type==="iframe"&&Y.url.includes("copilot.fun"));if(!X)return console.error("[bing] No copilot.fun iframe target found"),{answer:""};let W=X.targetId.slice(0,8),U=await G(["eval",W,"(()=>{const iframe=document.querySelector('iframe'); if(!iframe) return''; try{const doc=iframe.contentDocument||iframe.contentWindow.document; return doc?.body?.innerText?.trim()||''}catch(e){return''}})()"]).catch(()=>"");if(U)return console.error(`[bing] DOM extraction succeeded (${U.length} chars)`),{answer:U};console.error("[bing] DOM extraction returned empty — falling through to visible retry")}catch(K){console.error(`[bing] DOM extraction failed: ${K.message}`)}return{answer:""}}var CZ=`Usage: node extractors/bing-copilot.mjs "<query>" [--tab <prefix>]
594
+ `;async function IZ(){let Z=await b(process.argv.slice(2));u(Z,CZ);let{query:Q,tabPrefix:K,short:$}=x(Z),H=Date.now(),X={engine:"bing",mode:process.env.GREEDY_SEARCH_VISIBLE==="1"?"visible":"headless",clipboardEmpty:null,fallbackUsed:null,blockedBy:null,verificationResult:null,inputReady:null};try{if(!K)await G(["list"]);let W=await w(K),U=await G(["eval",W,"document.location.href"]).catch(()=>""),Y=!1;try{let O=new URL(U).hostname.toLowerCase();Y=O==="copilot.microsoft.com"||O.endsWith(".copilot.microsoft.com")}catch{}if(!Y)await G(["nav",W,"https://copilot.microsoft.com/"],20000),await new Promise((O)=>setTimeout(O,600));await S(W,G);let D=await T(W,G,1e4);if(X.verificationResult=D,D==="needs-human")throw Error("Copilot verification required — please solve it manually in the browser window");if(D==="clicked"){await new Promise((B)=>setTimeout(B,E.afterVerify));let O=await G(["eval",W,"document.location.href"]).catch(()=>""),V=!1;try{let B=new URL(O).hostname.toLowerCase();V=B==="copilot.microsoft.com"||B.endsWith(".copilot.microsoft.com")}catch{}if(!V)await G(["nav",W,"https://copilot.microsoft.com/"],20000),await new Promise((B)=>setTimeout(B,600)),await S(W,G)}if(await s(W))throw Error("Copilot requires sign-in — please sign in with Microsoft, Apple, or Google in the visible browser window. Once signed in, cookies persist for future runs.");let z=await m(W,L.input,15000,500);if(X.inputReady=z,await new Promise((O)=>setTimeout(O,M(300))),!z){if(await s(W))throw Error("Copilot requires sign-in — please sign in with Microsoft, Apple, or Google in the visible browser window. Once signed in, cookies persist for future runs.");throw Error("Copilot input not found — verification may have failed or page is in unexpected state")}await f(W,F),await G(["click",W,L.input]),await new Promise((O)=>setTimeout(O,E.postClick)),await G(["type",W,Q]),await new Promise((O)=>setTimeout(O,E.postType)),await G(["eval",W,`document.querySelector('${L.input}')?.dispatchEvent(new KeyboardEvent('keydown',{key:'Enter',bubbles:true,keyCode:13})), 'ok'`]),setTimeout(()=>{T(W,G,1e4).then((O)=>{if(O==="clicked")console.error("[bing] Post-submit verification clicked"),X.verificationResult="post-submit-clicked"}).catch(()=>{})},2000),await g(W,{timeout:$?25000:60000,minLength:50,selector:"document.querySelector('article') || document.body"});let{answer:_,sources:N}=await MZ(W,X,Q);if(!_)throw Error("No answer extracted — Copilot may not have responded");let j=await G(["eval",W,"document.location.href"]).catch(()=>"");X.durationMs=Date.now()-H,l({query:Q,url:j,answer:p(_,$),sources:N,_envelope:P(X)})}catch(W){X.durationMs=Date.now()-H,d(W,P(X))}}IZ();