@duckmind/dm-darwin-arm64 0.52.6 → 0.53.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dm +0 -0
- package/extensions/.dm-extensions.json +14 -10
- package/extensions/dm-cua/bin/browser-cua.mjs +6 -6
- package/extensions/dm-cua/index.js +5 -5
- package/extensions/dm-cua/src/browser-cua-lib.mjs +2 -2
- package/extensions/greedysearch-dm/bin/cdp-greedy.mjs +8 -1
- package/extensions/greedysearch-dm/bin/cdp-headless.mjs +1 -1
- package/extensions/greedysearch-dm/bin/cdp-visible.mjs +1 -1
- package/extensions/greedysearch-dm/bin/cdp.mjs +29 -20
- package/extensions/greedysearch-dm/bin/gschrome.mjs +1 -8
- package/extensions/greedysearch-dm/bin/kill-visible.mjs +1 -1
- package/extensions/greedysearch-dm/bin/launch-visible.mjs +1 -2
- package/extensions/greedysearch-dm/bin/launch.mjs +9 -11
- package/extensions/greedysearch-dm/bin/mcp.mjs +375 -0
- package/extensions/greedysearch-dm/bin/search.mjs +309 -157
- package/extensions/greedysearch-dm/bin/visible.mjs +1 -1
- package/extensions/greedysearch-dm/extractors/bing-copilot.mjs +205 -68
- package/extensions/greedysearch-dm/extractors/chatgpt.mjs +229 -140
- package/extensions/greedysearch-dm/extractors/common.mjs +160 -50
- package/extensions/greedysearch-dm/extractors/consensus.mjs +226 -93
- package/extensions/greedysearch-dm/extractors/consent.mjs +44 -17
- package/extensions/greedysearch-dm/extractors/gemini.mjs +277 -138
- package/extensions/greedysearch-dm/extractors/google-ai.mjs +172 -64
- package/extensions/greedysearch-dm/extractors/logically.mjs +183 -69
- package/extensions/greedysearch-dm/extractors/perplexity.mjs +331 -65
- package/extensions/greedysearch-dm/extractors/semantic-scholar.mjs +118 -41
- package/extensions/greedysearch-dm/index.js +23 -20
- package/extensions/greedysearch-dm/package.json +8 -3
- package/extensions/greedysearch-dm/skills/greedy-search/skill.md +8 -8
- package/extensions/greedysearch-dm/src/fetcher.mjs +2 -2
- package/extensions/greedysearch-dm/src/formatters/results.js +8 -6
- package/extensions/greedysearch-dm/src/github.mjs +7 -7
- package/extensions/greedysearch-dm/src/reddit.mjs +1 -1
- package/extensions/greedysearch-dm/src/search/browser-lifecycle.mjs +10 -8
- package/extensions/greedysearch-dm/src/search/challenge-detect.mjs +48 -0
- package/extensions/greedysearch-dm/src/search/chrome.mjs +130 -54
- package/extensions/greedysearch-dm/src/search/constants.mjs +6 -6
- package/extensions/greedysearch-dm/src/search/engines.mjs +9 -9
- package/extensions/greedysearch-dm/src/search/fetch-source.mjs +160 -83
- package/extensions/greedysearch-dm/src/search/minimize.mjs +1 -0
- package/extensions/greedysearch-dm/src/search/paths.mjs +1 -1
- package/extensions/greedysearch-dm/src/search/pdf.mjs +1 -1
- package/extensions/greedysearch-dm/src/search/port-pid.mjs +1 -1
- package/extensions/greedysearch-dm/src/search/progress.mjs +2 -0
- package/extensions/greedysearch-dm/src/search/recovery.mjs +1 -1
- package/extensions/greedysearch-dm/src/search/research.mjs +262 -167
- package/extensions/greedysearch-dm/src/search/scale-aware.mjs +11 -0
- package/extensions/greedysearch-dm/src/search/simple-research.mjs +827 -0
- package/extensions/greedysearch-dm/src/search/synthesis-runner.mjs +9 -9
- package/extensions/greedysearch-dm/src/search/synthesis.mjs +10 -10
- package/extensions/greedysearch-dm/src/tools/greedy-search-handler.js +23 -20
- package/extensions/greedysearch-dm/src/tools/shared.js +10 -9
- package/extensions/greedysearch-dm/src/utils/node-runtime.mjs +1 -1
- package/package.json +1 -1
- package/extensions/greedysearch-dm/src/search/cdp-endpoint.mjs +0 -3
- package/extensions/greedysearch-dm/src/search/launcher-paths.mjs +0 -3
- package/extensions/greedysearch-dm/src/search/partial-output.mjs +0 -1
- package/extensions/greedysearch-dm/src/utils/browser-executable.mjs +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{randomInt as
|
|
2
|
-
`)[0]?.slice(0,8);if(!
|
|
3
|
-
`)}return
|
|
1
|
+
import{randomInt as E}from"node:crypto";import{spawn as A}from"node:child_process";import{basename as D}from"node:path";function C(K=process.env,Q=process.execPath){let X=K.GREEDY_SEARCH_NODE||K.NODE_BINARY||K.NODE;if(X?.trim())return X.trim();let Y=D(Q||"").toLowerCase();if(Y==="node"||Y==="node.exe")return Q;return"node"}import{dirname as T,join as w}from"node:path";import{fileURLToPath as B}from"node:url";var R=T(B(import.meta.url)),z=w(R,"..","bin","cdp.mjs"),y=new Set(["list","snap","eval","shot","html","nav","net","click","clickxy","type","loadall","evalraw","browse","stop","--tab"]);function V(K){if(!Array.isArray(K)||K.length===0)throw Error("cdp: args must be a non-empty array");if(K[0]==="test")return K.map((Q,X)=>F(Q,X));if(!y.has(K[0]))throw Error(`cdp: unknown subcommand '${K[0]}'`);return K.map((Q,X)=>F(Q,X))}function F(K,Q){if(typeof K!=="string")throw Error(`cdp: argv[${Q}] must be a string (got ${typeof K})`);if(K.includes("\x00"))throw Error(`cdp: argv[${Q}] contains a null byte`);return K}function O(K,Q=30000){return L(K,null,Q)}function L(K,Q=null,X=30000){let Y=V(K);return new Promise((Z,q)=>{let $=A(C(),[z,...Y],{stdio:[Q==null?"ignore":"pipe","pipe","pipe"]});if(Q!=null)$.stdin.write(Q),$.stdin.end();let J="",W="";$.stdout.on("data",(H)=>J+=H),$.stderr.on("data",(H)=>W+=H);let G=setTimeout(()=>{$.kill(),q(Error(`cdp timeout: ${K[0]}`))},X);$.on("close",(H)=>{if(clearTimeout(G),H===0)Z(J.trim());else q(Error(W.trim()||`cdp exit ${H}`))})})}function m(K,Q){let X=($)=>String($??"").replace(/\s+/g," ").trim(),Y=X(K),Z=X(Q);if(!Z)return!1;if(Y.length<Math.ceil(Z.length*0.8))return!1;let q=Math.min(40,Z.length);return Y.includes(Z.slice(0,q))&&Y.includes(Z.slice(-q))}async function x(K){if(K)return K;let X=(await O(["list"])).split(`
|
|
2
|
+
`)[0]?.slice(0,8);if(!X)throw Error("No Chrome tabs found. Is Chrome running with --remote-debugging-port=9222?");let Y=await O(["evalraw",X,"Target.createTarget",'{"url":"about:blank"}']),Z;try{Z=JSON.parse(Y)}catch(J){throw Error(`Target.createTarget returned invalid JSON: ${J.message}`)}let{targetId:q}=Z;if(!q)throw Error("Target.createTarget did not return a targetId");await O(["list"]);let $=q.slice(0,8);try{await j($)}catch(J){process.stderr.write(`[getOrOpenTab] stealth injection failed: ${J.message}
|
|
3
|
+
`)}return $}async function g(K,Q){let X=`
|
|
4
4
|
(() => {
|
|
5
|
-
window.${
|
|
5
|
+
window.${Q} = null;
|
|
6
6
|
const _clipboard = navigator.clipboard;
|
|
7
7
|
if (!_clipboard) return;
|
|
8
8
|
const _origWriteText = typeof _clipboard.writeText === 'function'
|
|
@@ -13,7 +13,7 @@ import{randomInt as _}from"node:crypto";import{spawn as D}from"node:child_proces
|
|
|
13
13
|
: null;
|
|
14
14
|
|
|
15
15
|
_clipboard.writeText = function(text) {
|
|
16
|
-
window.${
|
|
16
|
+
window.${Q} = String(text ?? '');
|
|
17
17
|
if (!_origWriteText) return Promise.resolve();
|
|
18
18
|
// The OS/browser clipboard write may be denied in automated Chrome or
|
|
19
19
|
// when the tab is not focused. We only need the captured text; returning
|
|
@@ -27,7 +27,7 @@ import{randomInt as _}from"node:crypto";import{spawn as D}from"node:child_proces
|
|
|
27
27
|
for (const item of items || []) {
|
|
28
28
|
if (item.types && item.types.includes('text/plain')) {
|
|
29
29
|
const blob = await item.getType('text/plain');
|
|
30
|
-
window.${
|
|
30
|
+
window.${Q} = await blob.text();
|
|
31
31
|
break;
|
|
32
32
|
}
|
|
33
33
|
}
|
|
@@ -37,7 +37,26 @@ import{randomInt as _}from"node:crypto";import{spawn as D}from"node:child_proces
|
|
|
37
37
|
catch (_) { return undefined; }
|
|
38
38
|
};
|
|
39
39
|
})();
|
|
40
|
-
`;await
|
|
40
|
+
`;await O(["eval",K,X])}async function p(K,Q,X,Y={}){let{timeoutMs:Z=2600}=Y,q=Y.retryClick!=null?Y.retryClick:Math.floor(Z*0.4),$=String.raw`
|
|
41
|
+
new Promise((resolve) => {
|
|
42
|
+
const _deadline = Date.now() + ${Z};
|
|
43
|
+
const _retryAt = Date.now() + ${q};
|
|
44
|
+
let _retried = false;
|
|
45
|
+
function _click() { try { ${Q}; } catch(_) {} }
|
|
46
|
+
function _poll() {
|
|
47
|
+
const val = window.${X};
|
|
48
|
+
if (val) { resolve(val); return; }
|
|
49
|
+
if (!_retried && Date.now() >= _retryAt) {
|
|
50
|
+
_retried = true;
|
|
51
|
+
_click();
|
|
52
|
+
}
|
|
53
|
+
if (Date.now() < _deadline) { setTimeout(_poll, 100); }
|
|
54
|
+
else { resolve(window.${X} || ''); }
|
|
55
|
+
}
|
|
56
|
+
_click();
|
|
57
|
+
_poll();
|
|
58
|
+
})
|
|
59
|
+
`;return await O(["eval",K,$],Z+5000).catch(()=>"")}async function j(K){await O(["evalraw",K,"Page.addScriptToEvaluateOnNewDocument",JSON.stringify({source:`
|
|
41
60
|
(function() {
|
|
42
61
|
// ── Runtime.enable / CDP detection masking ──────────────
|
|
43
62
|
try { delete window.__REBROWSER_RUNTIME_ENABLE; } catch(_) {}
|
|
@@ -48,40 +67,62 @@ import{randomInt as _}from"node:crypto";import{spawn as D}from"node:child_proces
|
|
|
48
67
|
try { delete window._phantom; } catch(_) {}
|
|
49
68
|
try { delete window.Buffer; } catch(_) {}
|
|
50
69
|
|
|
51
|
-
// Real Chrome without automation
|
|
52
|
-
// A literal false
|
|
53
|
-
//
|
|
54
|
-
|
|
70
|
+
// Real Chrome without automation should not expose navigator.webdriver at all.
|
|
71
|
+
// A literal false or an own-property getter returning undefined is itself a
|
|
72
|
+
// common stealth tell; remove both instance and prototype properties when the
|
|
73
|
+
// descriptor is configurable (as it is with --disable-blink-features).
|
|
74
|
+
try { delete navigator.webdriver; } catch(_) {}
|
|
75
|
+
try { delete Navigator.prototype.webdriver; } catch(_) {}
|
|
55
76
|
Object.defineProperty(navigator, 'vendor', { get: () => 'Google Inc.', configurable: true });
|
|
56
77
|
Object.defineProperty(navigator, 'platform', { get: () => 'Win32', configurable: true });
|
|
57
78
|
Object.defineProperty(navigator, 'maxTouchPoints', { get: () => 0, configurable: true });
|
|
58
79
|
Object.defineProperty(navigator, 'pdfViewerEnabled', { get: () => true, configurable: true });
|
|
80
|
+
Object.defineProperty(navigator, 'productSub', { get: () => '20030107', configurable: true });
|
|
81
|
+
Object.defineProperty(navigator, 'product', { get: () => 'Gecko', configurable: true });
|
|
82
|
+
var __greedyMimeTypes = null;
|
|
83
|
+
function __makeMimeTypes() {
|
|
84
|
+
var pdf = { type: 'application/pdf', suffixes: 'pdf', description: 'Portable Document Format', enabledPlugin: null };
|
|
85
|
+
var textPdf = { type: 'text/pdf', suffixes: 'pdf', description: 'Portable Document Format', enabledPlugin: null };
|
|
86
|
+
try { Object.setPrototypeOf(pdf, MimeType.prototype); } catch(_) {}
|
|
87
|
+
try { Object.setPrototypeOf(textPdf, MimeType.prototype); } catch(_) {}
|
|
88
|
+
var m = [pdf, textPdf];
|
|
89
|
+
try { Object.setPrototypeOf(m, MimeTypeArray.prototype); } catch(_) {}
|
|
90
|
+
m.item = function item(i) { return this[i] || null; };
|
|
91
|
+
m.namedItem = function namedItem(name) { return Array.prototype.find.call(this, function(x) { return x && x.type === name; }) || null; };
|
|
92
|
+
return m;
|
|
93
|
+
}
|
|
59
94
|
Object.defineProperty(navigator, 'plugins', {
|
|
60
95
|
get: () => {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
96
|
+
__greedyMimeTypes = __greedyMimeTypes || __makeMimeTypes();
|
|
97
|
+
var plugin0 = { name: 'Chrome PDF Plugin', filename: 'internal-pdf-viewer', description: 'Portable Document Format' };
|
|
98
|
+
var plugin1 = { name: 'Chrome PDF Viewer', filename: 'mhjfbmdgcfjbbpaeojofohoefgiehjai', description: '' };
|
|
99
|
+
var plugin2 = { name: 'Native Client', filename: 'internal-nacl-plugin', description: '' };
|
|
100
|
+
try { Object.setPrototypeOf(plugin0, Plugin.prototype); } catch(_) {}
|
|
101
|
+
try { Object.setPrototypeOf(plugin1, Plugin.prototype); } catch(_) {}
|
|
102
|
+
try { Object.setPrototypeOf(plugin2, Plugin.prototype); } catch(_) {}
|
|
103
|
+
var p = [plugin0, plugin1, plugin2];
|
|
104
|
+
p.item = function item(i) { return this[i] || null; };
|
|
105
|
+
p.namedItem = function namedItem(name) { return Array.prototype.find.call(this, function(x) { return x && x.name === name; }) || null; };
|
|
106
|
+
p.refresh = function refresh() {};
|
|
107
|
+
try { Object.setPrototypeOf(p, PluginArray.prototype); } catch(_) {}
|
|
108
|
+
try {
|
|
109
|
+
__greedyMimeTypes[0].enabledPlugin = p[0];
|
|
110
|
+
__greedyMimeTypes[1].enabledPlugin = p[0];
|
|
111
|
+
} catch(_) {}
|
|
67
112
|
return p;
|
|
68
113
|
},
|
|
114
|
+
configurable: true,
|
|
69
115
|
});
|
|
70
116
|
Object.defineProperty(navigator, 'mimeTypes', {
|
|
71
117
|
get: () => {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
{ type: 'text/pdf', suffixes: 'pdf', description: 'Portable Document Format', enabledPlugin: null },
|
|
75
|
-
];
|
|
76
|
-
m.item = function(i) { return m[i] || null; };
|
|
77
|
-
m.namedItem = function(name) { return m.find(function(x) { return x.type === name; }) || null; };
|
|
78
|
-
return m;
|
|
118
|
+
__greedyMimeTypes = __greedyMimeTypes || __makeMimeTypes();
|
|
119
|
+
return __greedyMimeTypes;
|
|
79
120
|
},
|
|
80
121
|
configurable: true,
|
|
81
122
|
});
|
|
82
123
|
Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'], configurable: true });
|
|
83
124
|
try {
|
|
84
|
-
Object.defineProperty(navigator, 'connection', { get: () => ({ effectiveType: '4g', rtt: 50, downlink: 10, saveData: false }), configurable: true });
|
|
125
|
+
Object.defineProperty(navigator, 'connection', { get: () => ({ effectiveType: '4g', rtt: 50, downlink: 10, downlinkMax: Infinity, saveData: false }), configurable: true });
|
|
85
126
|
} catch(_) {}
|
|
86
127
|
if (!navigator.mediaDevices) {
|
|
87
128
|
Object.defineProperty(navigator, 'mediaDevices', {
|
|
@@ -97,6 +138,18 @@ import{randomInt as _}from"node:crypto";import{spawn as D}from"node:child_proces
|
|
|
97
138
|
configurable: true,
|
|
98
139
|
});
|
|
99
140
|
}
|
|
141
|
+
// ── Missing platform APIs (headless often lacks these) ─
|
|
142
|
+
try {
|
|
143
|
+
if (!navigator.share) {
|
|
144
|
+
navigator.share = function() { return Promise.reject(new Error('NotAllowedError')); };
|
|
145
|
+
}
|
|
146
|
+
} catch(_) {}
|
|
147
|
+
try {
|
|
148
|
+
if (!navigator.contentIndex) {
|
|
149
|
+
Object.defineProperty(navigator, 'contentIndex', { get: () => ({ add: function() {}, delete: function() {}, getAll: function() { return Promise.resolve([]); } }), configurable: true });
|
|
150
|
+
}
|
|
151
|
+
} catch(_) {}
|
|
152
|
+
|
|
100
153
|
if (!window.chrome) {
|
|
101
154
|
window.chrome = {
|
|
102
155
|
app: { isInstalled: false, InstallState: {}, RunningState: {} },
|
|
@@ -104,8 +157,8 @@ import{randomInt as _}from"node:crypto";import{spawn as D}from"node:child_proces
|
|
|
104
157
|
OnInstalledReason: {}, OnRestartRequiredReason: {}, PlatformArch: {}, PlatformNaclArch: {}, PlatformOs: {}, RequestUpdateCheckStatus: {},
|
|
105
158
|
connect: () => ({}), sendMessage: () => {}, onMessage: { addListener: () => {} }
|
|
106
159
|
},
|
|
107
|
-
loadTimes: ()
|
|
108
|
-
csi: ()
|
|
160
|
+
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' }; },
|
|
161
|
+
csi: function() { var t = Date.now(); return { onloadT: t - 2000, startE: t - 5000, pageT: 'back', tran: 2 }; },
|
|
109
162
|
};
|
|
110
163
|
}
|
|
111
164
|
var __greedyNativeFns = [];
|
|
@@ -126,6 +179,19 @@ import{randomInt as _}from"node:crypto";import{spawn as D}from"node:child_proces
|
|
|
126
179
|
return getParam.call(this, p);
|
|
127
180
|
});
|
|
128
181
|
} catch(_) {}
|
|
182
|
+
// ── WebGL readPixels noise ──────────────────────────
|
|
183
|
+
// CreepJS and other fingerprinters draw content with WebGL and read back the
|
|
184
|
+
// rendered pixels. Adding subtle noise breaks rendering-based fingerprinting.
|
|
185
|
+
try {
|
|
186
|
+
var origReadPixels = WebGLRenderingContext.prototype.readPixels;
|
|
187
|
+
WebGLRenderingContext.prototype.readPixels = __markNative(function readPixels(x, y, width, height, format, type, pixels) {
|
|
188
|
+
var result = origReadPixels.call(this, x, y, width, height, format, type, pixels);
|
|
189
|
+
if (pixels && pixels.length > 0) {
|
|
190
|
+
pixels[0] ^= 1;
|
|
191
|
+
}
|
|
192
|
+
return result;
|
|
193
|
+
});
|
|
194
|
+
} catch(_) {}
|
|
129
195
|
Object.defineProperty(navigator, 'hardwareConcurrency', { get: () => 8, configurable: true });
|
|
130
196
|
Object.defineProperty(navigator, 'deviceMemory', { get: () => 8, configurable: true });
|
|
131
197
|
|
|
@@ -133,7 +199,7 @@ import{randomInt as _}from"node:crypto";import{spawn as D}from"node:child_proces
|
|
|
133
199
|
// Headless rendering engines produce slightly different canvas output
|
|
134
200
|
// than headed Chrome. Subtle noise breaks hash-based fingerprinting.
|
|
135
201
|
try {
|
|
136
|
-
var __canvasNoise = ((Date.now()
|
|
202
|
+
var __canvasNoise = ((Date.now() & 0xFF) | 1);
|
|
137
203
|
var origFill = CanvasRenderingContext2D.prototype.fillText;
|
|
138
204
|
CanvasRenderingContext2D.prototype.fillText = __markNative(function fillText() {
|
|
139
205
|
this.globalAlpha = 0.9995;
|
|
@@ -152,15 +218,39 @@ import{randomInt as _}from"node:crypto";import{spawn as D}from"node:child_proces
|
|
|
152
218
|
HTMLCanvasElement.prototype.toDataURL = __markNative(function toDataURL() {
|
|
153
219
|
var ctx = this.getContext('2d');
|
|
154
220
|
if (ctx) {
|
|
155
|
-
//
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
221
|
+
// Spread noise across canvas to break hash-based fingerprinting.
|
|
222
|
+
// Uses a deterministic pattern so it's consistent per page load
|
|
223
|
+
// but varies between sessions.
|
|
224
|
+
var w = this.width, h = this.height;
|
|
225
|
+
if (w > 0 && h > 0) {
|
|
226
|
+
var imgData = ctx.getImageData(0, 0, Math.min(w, 4), Math.min(h, 4));
|
|
227
|
+
if (imgData && imgData.data) {
|
|
228
|
+
for (var __i = 0; __i < imgData.data.length; __i += 4) {
|
|
229
|
+
imgData.data[__i] ^= (__canvasNoise + __i) & 0xFF;
|
|
230
|
+
}
|
|
231
|
+
ctx.putImageData(imgData, 0, 0);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
159
234
|
}
|
|
160
235
|
return origToDataURL.apply(this, arguments);
|
|
161
236
|
});
|
|
162
237
|
} catch(_) {}
|
|
163
238
|
|
|
239
|
+
// ── AudioContext fingerprint noise ────────────────────
|
|
240
|
+
// Headless Chrome's AudioContext produces slightly different output.
|
|
241
|
+
// Subtle noise breaks audio-based fingerprinting.
|
|
242
|
+
try {
|
|
243
|
+
var __audioSeed = ((Date.now() & 0x1F) | 1);
|
|
244
|
+
var origGetChannelData = AudioBuffer.prototype.getChannelData;
|
|
245
|
+
AudioBuffer.prototype.getChannelData = __markNative(function getChannelData(channel) {
|
|
246
|
+
var data = origGetChannelData.call(this, channel);
|
|
247
|
+
for (var __i = 0; __i < data.length; __i += 64) {
|
|
248
|
+
data[__i] *= 0.99999;
|
|
249
|
+
}
|
|
250
|
+
return data;
|
|
251
|
+
});
|
|
252
|
+
} catch(_) {}
|
|
253
|
+
|
|
164
254
|
// ── window outer dimensions ──────────────────────────
|
|
165
255
|
// outerWidth/Height = 0 in headless — a well-known bot signal.
|
|
166
256
|
// Mirror innerWidth/Height (set by --window-size flag) so the ratio is sane.
|
|
@@ -170,9 +260,15 @@ import{randomInt as _}from"node:crypto";import{spawn as D}from"node:child_proces
|
|
|
170
260
|
} catch(_) {}
|
|
171
261
|
|
|
172
262
|
// ── screen properties ─────────────────────────────────
|
|
263
|
+
// Headless Chrome often reports an 800x600 screen even when the viewport is
|
|
264
|
+
// 1920x1080. Keep screen metrics internally consistent with our launch flags.
|
|
173
265
|
try {
|
|
174
|
-
|
|
175
|
-
|
|
266
|
+
Object.defineProperty(screen, 'width', { get: () => 1920, configurable: true });
|
|
267
|
+
Object.defineProperty(screen, 'height', { get: () => 1080, configurable: true });
|
|
268
|
+
Object.defineProperty(screen, 'availWidth', { get: () => 1920, configurable: true });
|
|
269
|
+
Object.defineProperty(screen, 'availHeight', { get: () => 1040, configurable: true });
|
|
270
|
+
Object.defineProperty(screen, 'colorDepth', { get: () => 24, configurable: true });
|
|
271
|
+
Object.defineProperty(screen, 'pixelDepth', { get: () => 24, configurable: true });
|
|
176
272
|
} catch(_) {}
|
|
177
273
|
|
|
178
274
|
// ── navigator.userAgentData (UA Client Hints) ─────────
|
|
@@ -245,10 +341,20 @@ import{randomInt as _}from"node:crypto";import{spawn as D}from"node:child_proces
|
|
|
245
341
|
};
|
|
246
342
|
} catch(_) {}
|
|
247
343
|
})();
|
|
248
|
-
`})])}function
|
|
344
|
+
`})])}function u(K){if(!K)return[];let Q=[],X=0;while(X<K.length&&Q.length<10){let Y=K.indexOf("[",X);if(Y===-1)break;let Z=K.indexOf("](",Y);if(Z===-1)break;let q=Z+2,$=-1;for(let J=q;J<K.length;J++){let W=K[J];if(W===")"){$=J;break}if(/\s/.test(W))break}if($!==-1){let J=K.slice(Y+1,Z),W=K.slice(q,$);if(/^https?:\/\//i.test(W)&&J){if(!Q.some((G)=>G.url===W))Q.push({title:J,url:W})}X=$+1}else X=Y+1}return Q}function N(K){if(!K)return!1;for(let Q=0;Q<K.length;Q++){let X=K.charCodeAt(Q);if(X<48||X>57)return!1}return!0}function d(K){if(!K)return[];let Q=[],X=new Map,Y=/^\[(\d+)\]:\s*(https?:\/\/[^\s"]+)(?:\s+"([^"]*)")?/gm,Z;while((Z=Y.exec(K))!==null){let $=Z[1],J=Z[2],W=Z[3]||"";X.set($,{url:J,title:W})}let q=0;while(q<K.length){let $=K.indexOf("[",q);if($===-1)break;let J=K.indexOf("]",$+1);if(J===-1)break;if(K[J+1]!=="["){q=$+1;continue}let W=K.indexOf("]",J+2);if(W===-1)break;let G=K.slice($+1,J),H=K.slice(J+2,W);if(N(H)){let U=X.get(H);if(U&&!Q.some((_)=>_.url===U.url))Q.push({title:G.trim()||U.title||"",url:U.url})}q=W+1}return Q}var S={postNav:800,postNavSlow:1200,postClick:300,postType:300,inputPoll:400,copyPoll:600,afterVerify:1500};async function c(K,Q,X={}){let{timeout:Y=60000,onPoll:Z}=X;if(!Z){let J=String.raw`
|
|
345
|
+
new Promise((resolve) => {
|
|
346
|
+
const _deadline = Date.now() + ${Y};
|
|
347
|
+
function _poll() {
|
|
348
|
+
if (document.querySelector('${Q}')) { resolve(true); return; }
|
|
349
|
+
if (Date.now() < _deadline) { setTimeout(_poll, 150); }
|
|
350
|
+
else { resolve(false); }
|
|
351
|
+
}
|
|
352
|
+
_poll();
|
|
353
|
+
})
|
|
354
|
+
`;if(await O(["eval",K,J],Y+5000).catch(()=>"false")==="true")return;throw Error(`Copy button ('${Q}') did not appear within ${Y}ms`)}let q=Date.now()+Y,$=0;while(Date.now()<q){if(await O(["eval",K,`!!document.querySelector('${Q}')`]).catch(()=>"false")==="true")return;await Z(++$).catch(()=>null),await new Promise((W)=>setTimeout(W,M(S.copyPoll)))}throw Error(`Copy button ('${Q}') did not appear within ${Y}ms`)}function M(K){let Q=K*0.2,X=E(-Math.floor(Q),Math.floor(Q)+1);return Math.max(50,Math.round(K+X))}async function i(K,Q={}){let{timeout:X=20000,interval:Y=600,stableRounds:Z=3,selector:q="document.body",minLength:$=0,isStreamingExpr:J="false"}=Q,W=String.raw`
|
|
249
355
|
new Promise((resolve, reject) => {
|
|
250
|
-
const _deadline = Date.now() + ${
|
|
251
|
-
const _baseInterval = ${
|
|
356
|
+
const _deadline = Date.now() + ${X};
|
|
357
|
+
const _baseInterval = ${Y};
|
|
252
358
|
const _stableRounds = ${Z};
|
|
253
359
|
const _minLength = ${$};
|
|
254
360
|
let _lastLen = -1;
|
|
@@ -261,9 +367,13 @@ import{randomInt as _}from"node:crypto";import{spawn as D}from"node:child_proces
|
|
|
261
367
|
function _poll() {
|
|
262
368
|
try {
|
|
263
369
|
// Re-query DOM each tick — element may not exist at eval start
|
|
264
|
-
const el = ${
|
|
265
|
-
const cur = el?.
|
|
266
|
-
|
|
370
|
+
const el = ${q};
|
|
371
|
+
const cur = el?.textContent?.length ?? 0;
|
|
372
|
+
const streaming = ${J};
|
|
373
|
+
if (streaming) {
|
|
374
|
+
if (cur !== _lastLen) _lastLen = cur;
|
|
375
|
+
_stableCount = 0;
|
|
376
|
+
} else if (cur >= _minLength) {
|
|
267
377
|
if (cur === _lastLen) {
|
|
268
378
|
_stableCount++;
|
|
269
379
|
if (_stableCount >= _stableRounds) { resolve(cur); return; }
|
|
@@ -275,18 +385,18 @@ import{randomInt as _}from"node:crypto";import{spawn as D}from"node:child_proces
|
|
|
275
385
|
if (Date.now() < _deadline) {
|
|
276
386
|
setTimeout(_poll, _jitter(_baseInterval));
|
|
277
387
|
} else {
|
|
278
|
-
if (_lastLen >= _minLength) { resolve(_lastLen); }
|
|
279
|
-
else { reject(new Error('Generation did not stabilise within ${
|
|
388
|
+
if (_lastLen >= _minLength && !streaming) { resolve(_lastLen); }
|
|
389
|
+
else { reject(new Error('Generation did not stabilise within ${X}ms')); }
|
|
280
390
|
}
|
|
281
391
|
} catch(e) { reject(e); }
|
|
282
392
|
}
|
|
283
393
|
|
|
284
394
|
_poll();
|
|
285
395
|
})
|
|
286
|
-
`,
|
|
396
|
+
`,G=await O(["eval",K,W],X+1e4),H=parseInt(G,10)||0;if(H>=$)return H;throw Error(`Generation did not stabilise within ${X}ms`)}async function l(K,Q,X=15000,Y=500){let Z=String.raw`
|
|
287
397
|
new Promise((resolve) => {
|
|
288
|
-
const _deadline = Date.now() + ${
|
|
289
|
-
const _baseInterval = ${
|
|
398
|
+
const _deadline = Date.now() + ${X};
|
|
399
|
+
const _baseInterval = ${Y};
|
|
290
400
|
|
|
291
401
|
function _jitter(ms) {
|
|
292
402
|
return Math.max(50, ms + (Math.random() * ms * 0.4 - ms * 0.2));
|
|
@@ -294,7 +404,7 @@ import{randomInt as _}from"node:crypto";import{spawn as D}from"node:child_proces
|
|
|
294
404
|
|
|
295
405
|
function _poll() {
|
|
296
406
|
try {
|
|
297
|
-
if (document.querySelector('${
|
|
407
|
+
if (document.querySelector('${Q}')) { resolve(true); return; }
|
|
298
408
|
if (Date.now() < _deadline) { setTimeout(_poll, _jitter(_baseInterval)); }
|
|
299
409
|
else { resolve(false); }
|
|
300
410
|
} catch(_) { resolve(false); }
|
|
@@ -302,7 +412,7 @@ import{randomInt as _}from"node:crypto";import{spawn as D}from"node:child_proces
|
|
|
302
412
|
|
|
303
413
|
_poll();
|
|
304
414
|
})
|
|
305
|
-
`;return await
|
|
306
|
-
`)}function
|
|
307
|
-
`)}process.stderr.write(`Error: ${
|
|
308
|
-
`),process.exit(1)}export{
|
|
415
|
+
`;return await O(["eval",K,Z],X+5000)==="true"}async function n(K){let Q=K.indexOf("--stdin");if(Q===-1)return K;let X=await new Promise((Z)=>{let q="";process.stdin.setEncoding("utf8"),process.stdin.on("data",($)=>q+=$),process.stdin.on("end",()=>Z(q.trim()))}),Y=[...K];return Y[Q]=X,Y}function s(K){let Q=K.includes("--short"),X=K.filter((W)=>W!=="--short"),Y=X.indexOf("--tab"),Z=Y===-1?null:X[Y+1];if(Y!==-1)X=X.filter((W,G)=>G!==Y&&G!==Y+1);let q=X.indexOf("--locale"),$=q===-1?null:X[q+1];if(q!==-1)X=X.filter((W,G)=>G!==q&&G!==q+1);return{query:X.join(" "),tabPrefix:Z,short:Q,locale:$}}function o(K,Q){if(!K.length||K[0]==="--help")process.stderr.write(Q),process.exit(1)}function r(K,Q,X=300){if(!Q||K.length<=X)return K;let Y=K.slice(0,X),Z=Y.lastIndexOf(" ");return Z>0?`${Y.slice(0,Z)}…`:`${Y}…`}function a(K){process.stdout.write(`${JSON.stringify(K,null,2)}
|
|
416
|
+
`)}function t(K,Q,X=null){if(!K||typeof K!=="object")return;let Y=X?` (+${Date.now()-X}ms)`:"";if(K.lastStage=Q,!Array.isArray(K.stages))K.stages=[];K.stages.push({stage:Q,at:Date.now()});let Z=K.engine||"extractor";console.error(`[${Z}] stage: ${Q}${Y}`)}function e({engine:K,mode:Q="headless",clipboardEmpty:X=null,fallbackUsed:Y=null,blockedBy:Z=null,verificationResult:q=null,inputReady:$=null,durationMs:J=null,lastStage:W=null,stages:G=null}={}){return{engine:K,mode:Q,clipboardEmpty:X,fallbackUsed:Y,blockedBy:Z,verificationResult:q,inputReady:$,durationMs:J,lastStage:W,stages:G}}function KK(K,Q=null){if(Q){let X=JSON.stringify({_envelope:Q,error:K.message});process.stdout.write(`${X}
|
|
417
|
+
`)}process.stderr.write(`Error: ${K.message}
|
|
418
|
+
`),process.exit(1)}export{i as waitForStreamComplete,l as waitForSelector,c as waitForCopyButton,m as verifyInputText,o as validateQuery,n as prepareArgs,d as parseSourcesFromMarkdownRefStyle,u as parseSourcesFromMarkdown,s as parseArgs,a as outputJson,t as logStage,M as jitter,j as injectHeadlessStealth,g as injectClipboardInterceptor,KK as handleError,x as getOrOpenTab,r as formatAnswer,p as clickCopyAndAwaitClipboard,L as cdpWithInput,O as cdp,e as buildEnvelope,S as TIMING};
|