@duckmind/dm-windows-x64 0.60.6 → 0.60.8
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.exe +0 -0
- package/extensions/.dm-extensions.json +70 -123
- package/extensions/dm-9router-ext/src/index.js +410 -5
- package/extensions/dm-caveman/extensions/caveman.js +283 -12
- package/extensions/dm-cliproxy/index.js +182 -2
- package/extensions/dm-cliproxy/scripts/check-config-migration.js +66 -8
- package/extensions/dm-cliproxy/src/apply.js +228 -1
- package/extensions/dm-cliproxy/src/cache.js +42 -1
- package/extensions/dm-cliproxy/src/commands.js +50 -2
- package/extensions/dm-cliproxy/src/compat.js +81 -1
- package/extensions/dm-cliproxy/src/config.js +192 -2
- package/extensions/dm-cliproxy/src/conflicts.js +46 -1
- package/extensions/dm-cliproxy/src/fetch-models.js +190 -1
- package/extensions/dm-cliproxy/src/fetch-usage.js +41 -1
- package/extensions/dm-cliproxy/src/log.js +23 -1
- package/extensions/dm-cliproxy/src/status-quota.js +77 -1
- package/extensions/dm-cliproxy/src/ui-frame.js +50 -1
- package/extensions/dm-cliproxy/src/ui-hub/hub.js +199 -2
- package/extensions/dm-cliproxy/src/ui-hub/index.js +26 -2
- package/extensions/dm-cliproxy/src/ui-hub/shell.js +46 -1
- package/extensions/dm-cliproxy/src/ui-hub/view-diagnostics.js +69 -1
- package/extensions/dm-cliproxy/src/ui-hub/view-models.js +379 -1
- package/extensions/dm-cliproxy/src/ui-hub/view-usage.js +106 -1
- package/extensions/dm-cliproxy/src/ui-picker/catalog.js +41 -1
- package/extensions/dm-cliproxy/src/ui-picker/mutate.js +115 -1
- package/extensions/dm-cliproxy/src/ui-picker/prompt-confirm.js +35 -1
- package/extensions/dm-cliproxy/src/ui-picker/prompt-name.js +62 -1
- package/extensions/dm-cliproxy/src/ui-picker/providers.js +45 -1
- package/extensions/dm-cliproxy/src/ui-picker/render-text.js +34 -1
- package/extensions/dm-cliproxy/src/ui-picker/rows.js +57 -1
- package/extensions/dm-cliproxy/src/ui-setup.js +260 -2
- package/extensions/dm-cliproxy/src/ui-usage.js +151 -1
- package/extensions/dm-cliproxy/src/usage-shared-cache.js +97 -1
- package/extensions/dm-context/src/context.js +144 -1
- package/extensions/dm-context/src/index.js +339 -7
- package/extensions/dm-context/src/utils.js +9 -1
- package/extensions/dm-cua/bin/browser-cua.mjs +73 -8
- package/extensions/dm-cua/index.js +75 -6
- package/extensions/dm-cua/src/browser-cua-lib.mjs +490 -6
- package/extensions/dm-cua/src/browser-install.mjs +331 -2
- package/extensions/dm-fff/src/index.js +688 -12
- package/extensions/dm-fff/src/query.js +60 -1
- package/extensions/dm-goal/src/goal.js +894 -23
- package/extensions/dm-image2/index.js +103 -9
- package/extensions/dm-image2/src/image-lib.mjs +1275 -8
- package/extensions/dm-subagents/install.mjs +62 -8
- package/extensions/dm-subagents/src/agents/agent-management.js +1190 -36
- package/extensions/dm-subagents/src/agents/agent-memory.js +216 -6
- package/extensions/dm-subagents/src/agents/agent-scope.js +5 -1
- package/extensions/dm-subagents/src/agents/agent-selection.js +20 -1
- package/extensions/dm-subagents/src/agents/agent-serializer.js +120 -5
- package/extensions/dm-subagents/src/agents/agents.js +1139 -11
- package/extensions/dm-subagents/src/agents/chain-serializer.js +299 -11
- package/extensions/dm-subagents/src/agents/frontmatter.js +65 -6
- package/extensions/dm-subagents/src/agents/identity.js +29 -1
- package/extensions/dm-subagents/src/agents/proactive-skills.js +141 -1
- package/extensions/dm-subagents/src/agents/skills.js +614 -6
- package/extensions/dm-subagents/src/extension/config.js +35 -2
- package/extensions/dm-subagents/src/extension/control-notices.js +69 -4
- package/extensions/dm-subagents/src/extension/doctor.js +172 -15
- package/extensions/dm-subagents/src/extension/fanout-child.js +158 -231
- package/extensions/dm-subagents/src/extension/index.js +521 -359
- package/extensions/dm-subagents/src/extension/rpc.js +266 -7
- package/extensions/dm-subagents/src/extension/schemas.js +275 -1
- package/extensions/dm-subagents/src/extension/tool-description.js +111 -6
- package/extensions/dm-subagents/src/intercom/intercom-bridge.js +126 -4
- package/extensions/dm-subagents/src/intercom/native-supervisor-channel.js +452 -5
- package/extensions/dm-subagents/src/intercom/result-intercom.js +319 -3
- package/extensions/dm-subagents/src/profiles/profiles.js +458 -3
- package/extensions/dm-subagents/src/runs/background/async-execution.js +834 -40
- package/extensions/dm-subagents/src/runs/background/async-job-tracker.js +435 -14
- package/extensions/dm-subagents/src/runs/background/async-resume.js +334 -8
- package/extensions/dm-subagents/src/runs/background/async-status.js +313 -12
- package/extensions/dm-subagents/src/runs/background/chain-append.js +245 -2
- package/extensions/dm-subagents/src/runs/background/chain-root-attachment.js +136 -1
- package/extensions/dm-subagents/src/runs/background/completion-batcher.js +94 -1
- package/extensions/dm-subagents/src/runs/background/completion-dedupe.js +54 -1
- package/extensions/dm-subagents/src/runs/background/control-channel.js +190 -1
- package/extensions/dm-subagents/src/runs/background/fleet-view.js +483 -17
- package/extensions/dm-subagents/src/runs/background/notify.js +129 -3
- package/extensions/dm-subagents/src/runs/background/parallel-groups.js +34 -1
- package/extensions/dm-subagents/src/runs/background/result-watcher.js +236 -6
- package/extensions/dm-subagents/src/runs/background/run-id-resolver.js +76 -4
- package/extensions/dm-subagents/src/runs/background/run-status.js +427 -23
- package/extensions/dm-subagents/src/runs/background/scheduled-runs.js +487 -4
- package/extensions/dm-subagents/src/runs/background/stale-run-reconciler.js +306 -9
- package/extensions/dm-subagents/src/runs/background/subagent-runner.js +2849 -73
- package/extensions/dm-subagents/src/runs/background/top-level-async.js +5 -1
- package/extensions/dm-subagents/src/runs/background/wait.js +206 -11
- package/extensions/dm-subagents/src/runs/foreground/chain-clarify.js +1013 -12
- package/extensions/dm-subagents/src/runs/foreground/chain-execution.js +980 -101
- package/extensions/dm-subagents/src/runs/foreground/execution.js +1165 -45
- package/extensions/dm-subagents/src/runs/foreground/subagent-executor.js +3157 -222
- package/extensions/dm-subagents/src/runs/shared/acceptance.js +835 -3
- package/extensions/dm-subagents/src/runs/shared/chain-outputs.js +104 -1
- package/extensions/dm-subagents/src/runs/shared/completion-guard.js +116 -3
- package/extensions/dm-subagents/src/runs/shared/dm-args.js +208 -1
- package/extensions/dm-subagents/src/runs/shared/dm-spawn.js +90 -1
- package/extensions/dm-subagents/src/runs/shared/dynamic-fanout.js +282 -1
- package/extensions/dm-subagents/src/runs/shared/long-running-guard.js +148 -1
- package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-allowlist.js +305 -1
- package/extensions/dm-subagents/src/runs/shared/model-fallback.js +194 -1
- package/extensions/dm-subagents/src/runs/shared/model-scope.js +65 -1
- package/extensions/dm-subagents/src/runs/shared/nested-events.js +851 -8
- package/extensions/dm-subagents/src/runs/shared/nested-path.js +41 -1
- package/extensions/dm-subagents/src/runs/shared/nested-render.js +105 -1
- package/extensions/dm-subagents/src/runs/shared/parallel-utils.js +81 -4
- package/extensions/dm-subagents/src/runs/shared/run-history.js +51 -4
- package/extensions/dm-subagents/src/runs/shared/single-output.js +149 -8
- package/extensions/dm-subagents/src/runs/shared/structured-output.js +58 -1
- package/extensions/dm-subagents/src/runs/shared/subagent-control.js +166 -5
- package/extensions/dm-subagents/src/runs/shared/subagent-prompt-runtime.js +329 -13
- package/extensions/dm-subagents/src/runs/shared/tool-budget.js +73 -1
- package/extensions/dm-subagents/src/runs/shared/turn-budget.js +47 -4
- package/extensions/dm-subagents/src/runs/shared/workflow-graph.js +196 -1
- package/extensions/dm-subagents/src/runs/shared/worktree.js +435 -3
- package/extensions/dm-subagents/src/shared/artifacts.js +92 -2
- package/extensions/dm-subagents/src/shared/atomic-json.js +55 -1
- package/extensions/dm-subagents/src/shared/child-transcript.js +167 -5
- package/extensions/dm-subagents/src/shared/file-coalescer.js +25 -1
- package/extensions/dm-subagents/src/shared/fork-context.js +147 -4
- package/extensions/dm-subagents/src/shared/formatters.js +98 -7
- package/extensions/dm-subagents/src/shared/jsonl-writer.js +56 -2
- package/extensions/dm-subagents/src/shared/model-info.js +62 -1
- package/extensions/dm-subagents/src/shared/post-exit-stdio-guard.js +68 -1
- package/extensions/dm-subagents/src/shared/session-identity.js +6 -1
- package/extensions/dm-subagents/src/shared/session-tokens.js +39 -2
- package/extensions/dm-subagents/src/shared/settings.js +198 -11
- package/extensions/dm-subagents/src/shared/status-format.js +53 -1
- package/extensions/dm-subagents/src/shared/types.js +184 -6
- package/extensions/dm-subagents/src/shared/utils.js +462 -2
- package/extensions/dm-subagents/src/slash/prompt-template-bridge.js +288 -1
- package/extensions/dm-subagents/src/slash/prompt-workflows.js +297 -7
- package/extensions/dm-subagents/src/slash/slash-bridge.js +118 -1
- package/extensions/dm-subagents/src/slash/slash-commands.js +1287 -31
- package/extensions/dm-subagents/src/slash/slash-live-state.js +240 -4
- package/extensions/dm-subagents/src/tui/render-helpers.js +64 -1
- package/extensions/dm-subagents/src/tui/render.js +1542 -4
- package/extensions/dm-usage/index.js +1294 -9
- package/extensions/greedysearch-dm/bin/cdp-greedy.mjs +40 -9
- package/extensions/greedysearch-dm/bin/cdp-headless.mjs +5 -2
- package/extensions/greedysearch-dm/bin/cdp-visible.mjs +5 -2
- package/extensions/greedysearch-dm/bin/cdp.mjs +896 -30
- package/extensions/greedysearch-dm/bin/gschrome.mjs +30 -2
- package/extensions/greedysearch-dm/bin/kill-visible.mjs +7 -2
- package/extensions/greedysearch-dm/bin/launch-visible.mjs +13 -2
- package/extensions/greedysearch-dm/bin/launch.mjs +282 -10
- package/extensions/greedysearch-dm/bin/mcp.mjs +386 -361
- package/extensions/greedysearch-dm/bin/search.mjs +620 -540
- package/extensions/greedysearch-dm/bin/visible.mjs +22 -2
- package/extensions/greedysearch-dm/extractors/bing-copilot.mjs +329 -579
- package/extensions/greedysearch-dm/extractors/chatgpt.mjs +301 -583
- package/extensions/greedysearch-dm/extractors/common.mjs +408 -32
- package/extensions/greedysearch-dm/extractors/consensus.mjs +376 -365
- package/extensions/greedysearch-dm/extractors/consent.mjs +303 -14
- package/extensions/greedysearch-dm/extractors/gemini.mjs +228 -592
- package/extensions/greedysearch-dm/extractors/google-ai.mjs +78 -499
- package/extensions/greedysearch-dm/extractors/logically.mjs +270 -347
- package/extensions/greedysearch-dm/extractors/perplexity.mjs +243 -581
- package/extensions/greedysearch-dm/extractors/selectors.mjs +32 -1
- package/extensions/greedysearch-dm/extractors/semantic-scholar.mjs +130 -317
- package/extensions/greedysearch-dm/index.js +123 -23
- package/extensions/greedysearch-dm/src/fetcher.mjs +576 -2
- package/extensions/greedysearch-dm/src/formatters/results.js +95 -10
- package/extensions/greedysearch-dm/src/formatters/sources.js +57 -1
- package/extensions/greedysearch-dm/src/formatters/synthesis.js +49 -1
- package/extensions/greedysearch-dm/src/github.mjs +222 -7
- package/extensions/greedysearch-dm/src/reddit.mjs +145 -14
- package/extensions/greedysearch-dm/src/search/browser-lifecycle.mjs +340 -9
- package/extensions/greedysearch-dm/src/search/challenge-detect.mjs +112 -4
- package/extensions/greedysearch-dm/src/search/chrome.mjs +486 -285
- package/extensions/greedysearch-dm/src/search/constants.mjs +109 -8
- package/extensions/greedysearch-dm/src/search/defaults.mjs +10 -1
- package/extensions/greedysearch-dm/src/search/engines.mjs +79 -9
- package/extensions/greedysearch-dm/src/search/fetch-source.mjs +441 -349
- package/extensions/greedysearch-dm/src/search/file-sources.mjs +29 -7
- package/extensions/greedysearch-dm/src/search/minimize.mjs +86 -1
- package/extensions/greedysearch-dm/src/search/output.mjs +51 -5
- package/extensions/greedysearch-dm/src/search/paths.mjs +48 -1
- package/extensions/greedysearch-dm/src/search/pdf.mjs +63 -2
- package/extensions/greedysearch-dm/src/search/port-pid.mjs +69 -1
- package/extensions/greedysearch-dm/src/search/progress.mjs +109 -2
- package/extensions/greedysearch-dm/src/search/query.mjs +21 -1
- package/extensions/greedysearch-dm/src/search/recovery.mjs +49 -1
- package/extensions/greedysearch-dm/src/search/research.mjs +2227 -458
- package/extensions/greedysearch-dm/src/search/scale-aware.mjs +61 -11
- package/extensions/greedysearch-dm/src/search/simple-research.mjs +396 -805
- package/extensions/greedysearch-dm/src/search/sources.mjs +412 -1
- package/extensions/greedysearch-dm/src/search/synthesis-runner.mjs +127 -12
- package/extensions/greedysearch-dm/src/search/synthesis.mjs +202 -12
- package/extensions/greedysearch-dm/src/tools/greedy-search-handler.js +209 -23
- package/extensions/greedysearch-dm/src/tools/shared.js +226 -10
- package/extensions/greedysearch-dm/src/utils/content.mjs +35 -4
- package/extensions/greedysearch-dm/src/utils/helpers.js +22 -1
- package/extensions/greedysearch-dm/src/utils/node-runtime.mjs +10 -1
- package/extensions/greedysearch-dm/src/utils/system-cmds.mjs +61 -1
- package/package.json +1 -1
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import{randomInt
|
|
1
|
+
import { randomInt } from "node:crypto";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import http from "node:http";
|
|
4
|
+
const CONSENT_JS = `
|
|
2
5
|
(function() {
|
|
3
6
|
// Google consent page (consent.google.com)
|
|
4
7
|
var g = document.querySelector('#L2AGLb, button[jsname="b3VHJd"], .tHlp8d');
|
|
@@ -15,7 +18,8 @@ import{randomInt as Y}from"node:crypto";import{existsSync as j,readFileSync as P
|
|
|
15
18
|
|
|
16
19
|
return null;
|
|
17
20
|
})()
|
|
18
|
-
|
|
21
|
+
`;
|
|
22
|
+
const VERIFY_DETECT_JS = `
|
|
19
23
|
(function() {
|
|
20
24
|
var url = document.location.href;
|
|
21
25
|
|
|
@@ -110,7 +114,8 @@ import{randomInt as Y}from"node:crypto";import{existsSync as j,readFileSync as P
|
|
|
110
114
|
|
|
111
115
|
return null;
|
|
112
116
|
})()
|
|
113
|
-
|
|
117
|
+
`;
|
|
118
|
+
const VERIFY_RETRY_JS = `
|
|
114
119
|
(function() {
|
|
115
120
|
var url = document.location.href;
|
|
116
121
|
var isVerifyPage = url.includes('/sorry/') ||
|
|
@@ -144,17 +149,301 @@ import{randomInt as Y}from"node:crypto";import{existsSync as j,readFileSync as P
|
|
|
144
149
|
|
|
145
150
|
return 'still-verifying';
|
|
146
151
|
})()
|
|
147
|
-
`;
|
|
148
|
-
|
|
149
|
-
|
|
152
|
+
`;
|
|
153
|
+
export async function dismissConsent(tab, cdp) {
|
|
154
|
+
const result = await cdp(["eval", tab, CONSENT_JS]).catch(() => null);
|
|
155
|
+
if (result && result !== "null") {
|
|
156
|
+
await new Promise((r) => setTimeout(r, 1500));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
function rng(min, max) {
|
|
160
|
+
return randomInt(min * 1000, max * 1000) / 1000;
|
|
161
|
+
}
|
|
162
|
+
async function browserLevelClick(x, y) {
|
|
163
|
+
if (!globalThis.WebSocket)
|
|
164
|
+
return;
|
|
165
|
+
const profileDir = process.env.CDP_PROFILE_DIR;
|
|
166
|
+
if (!profileDir)
|
|
167
|
+
return;
|
|
168
|
+
const portFile = `${profileDir.replaceAll("\\", "/")}/DevToolsActivePort`;
|
|
169
|
+
if (!existsSync(portFile))
|
|
170
|
+
return;
|
|
171
|
+
const port = readFileSync(portFile, "utf8").trim().split(`
|
|
172
|
+
`)[0];
|
|
173
|
+
const version = await new Promise((resolve, reject) => {
|
|
174
|
+
const req = http.get(`http://localhost:${port}/json/version`, (res) => {
|
|
175
|
+
let body = "";
|
|
176
|
+
res.on("data", (d) => body += d);
|
|
177
|
+
res.on("end", () => {
|
|
178
|
+
try {
|
|
179
|
+
resolve(JSON.parse(body));
|
|
180
|
+
} catch {
|
|
181
|
+
reject(new Error("bad JSON"));
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
req.on("error", reject);
|
|
186
|
+
req.setTimeout(1000, () => {
|
|
187
|
+
req.destroy();
|
|
188
|
+
reject(new Error("timeout"));
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
const ws = new globalThis.WebSocket(version.webSocketDebuggerUrl);
|
|
192
|
+
let msgId = 0;
|
|
193
|
+
await new Promise((resolve) => {
|
|
194
|
+
ws.onopen = async () => {
|
|
195
|
+
const send = (method, params) => new Promise((r) => {
|
|
196
|
+
const id = ++msgId;
|
|
197
|
+
const handler = (evt) => {
|
|
198
|
+
if (JSON.parse(evt.data).id === id) {
|
|
199
|
+
ws.removeEventListener("message", handler);
|
|
200
|
+
r();
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
ws.addEventListener("message", handler);
|
|
204
|
+
ws.send(JSON.stringify({ id, method, params }));
|
|
205
|
+
});
|
|
206
|
+
const cx = x + rng(-2, 2);
|
|
207
|
+
const cy = y + rng(-2, 2);
|
|
208
|
+
await send("Input.dispatchMouseEvent", {
|
|
209
|
+
type: "mouseMoved",
|
|
210
|
+
x: cx,
|
|
211
|
+
y: cy,
|
|
212
|
+
button: "none"
|
|
213
|
+
});
|
|
214
|
+
await new Promise((r) => setTimeout(r, rng(80, 160)));
|
|
215
|
+
await send("Input.dispatchMouseEvent", {
|
|
216
|
+
type: "mousePressed",
|
|
217
|
+
x: cx,
|
|
218
|
+
y: cy,
|
|
219
|
+
button: "left",
|
|
220
|
+
clickCount: 1
|
|
221
|
+
});
|
|
222
|
+
await new Promise((r) => setTimeout(r, rng(30, 80)));
|
|
223
|
+
await send("Input.dispatchMouseEvent", {
|
|
224
|
+
type: "mouseReleased",
|
|
225
|
+
x: cx + rng(-1, 1),
|
|
226
|
+
y: cy + rng(-1, 1),
|
|
227
|
+
button: "left",
|
|
228
|
+
clickCount: 1
|
|
229
|
+
});
|
|
230
|
+
setTimeout(() => {
|
|
231
|
+
ws.close();
|
|
232
|
+
resolve();
|
|
233
|
+
}, 200);
|
|
234
|
+
};
|
|
235
|
+
ws.onerror = () => resolve();
|
|
236
|
+
setTimeout(resolve, 3000);
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
export async function humanClickXY(tab, cdpFn, x, y) {
|
|
240
|
+
const cx = Number.parseFloat(x);
|
|
241
|
+
const cy = Number.parseFloat(y);
|
|
242
|
+
if (Number.isNaN(cx) || Number.isNaN(cy)) {
|
|
243
|
+
throw new Error(`humanClickXY: invalid coordinates (${x}, ${y})`);
|
|
244
|
+
}
|
|
245
|
+
const base = { button: "left", clickCount: 1, modifiers: 0 };
|
|
246
|
+
const jx = cx + rng(-3, 3);
|
|
247
|
+
const jy = cy + rng(-3, 3);
|
|
248
|
+
await cdpFn([
|
|
249
|
+
"evalraw",
|
|
250
|
+
tab,
|
|
251
|
+
"Input.dispatchMouseEvent",
|
|
252
|
+
JSON.stringify({ ...base, type: "mouseMoved", x: jx, y: jy })
|
|
253
|
+
]);
|
|
254
|
+
await new Promise((r) => setTimeout(r, rng(80, 180)));
|
|
255
|
+
const px = cx + rng(-2, 2);
|
|
256
|
+
const py = cy + rng(-2, 2);
|
|
257
|
+
await cdpFn([
|
|
258
|
+
"evalraw",
|
|
259
|
+
tab,
|
|
260
|
+
"Input.dispatchMouseEvent",
|
|
261
|
+
JSON.stringify({ ...base, type: "mousePressed", x: px, y: py })
|
|
262
|
+
]);
|
|
263
|
+
await new Promise((r) => setTimeout(r, rng(30, 90)));
|
|
264
|
+
const rx = px + rng(-1, 1);
|
|
265
|
+
const ry = py + rng(-1, 1);
|
|
266
|
+
await cdpFn([
|
|
267
|
+
"evalraw",
|
|
268
|
+
tab,
|
|
269
|
+
"Input.dispatchMouseEvent",
|
|
270
|
+
JSON.stringify({ ...base, type: "mouseReleased", x: rx, y: ry })
|
|
271
|
+
]);
|
|
272
|
+
await browserLevelClick(cx, cy).catch(() => {});
|
|
273
|
+
await new Promise((r) => setTimeout(r, rng(100, 300)));
|
|
274
|
+
return `human-clicked at (${cx.toFixed(0)}, ${cy.toFixed(0)})`;
|
|
275
|
+
}
|
|
276
|
+
export async function humanClickElement(tab, cdpFn, selector) {
|
|
277
|
+
const rect = await cdpFn([
|
|
278
|
+
"eval",
|
|
279
|
+
tab,
|
|
280
|
+
`(function() {
|
|
281
|
+
var el = document.querySelector('${selector.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}');
|
|
150
282
|
if (!el) return 'null';
|
|
151
283
|
var r = el.getBoundingClientRect();
|
|
152
284
|
return JSON.stringify({x: r.left + r.width / 2, y: r.top + r.height / 2, w: r.width, h: r.height});
|
|
153
|
-
})()`
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
285
|
+
})()`
|
|
286
|
+
]).catch(() => "null");
|
|
287
|
+
if (!rect || rect === "null") {
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
const parsed = JSON.parse(rect);
|
|
291
|
+
if (parsed.w === 0 || parsed.h === 0 || parsed.x === 0 && parsed.y === 0) {
|
|
292
|
+
return null;
|
|
293
|
+
}
|
|
294
|
+
const { x, y } = parsed;
|
|
295
|
+
return humanClickXY(tab, cdpFn, x, y);
|
|
296
|
+
}
|
|
297
|
+
function tryHumanClick(tab, cdp, detectResult) {
|
|
298
|
+
if (!detectResult || detectResult === "null" || detectResult === "cleared" || detectResult === "still-verifying" || detectResult === "cf-closed-shadow-dom")
|
|
299
|
+
return Promise.resolve("no-challenge");
|
|
300
|
+
try {
|
|
301
|
+
const info = JSON.parse(detectResult);
|
|
302
|
+
if (info.t === "sel" && info.s) {
|
|
303
|
+
process.stderr.write(`[greedysearch] Human-clicking "${info.txt}" via CDP...
|
|
304
|
+
`);
|
|
305
|
+
return humanClickElement(tab, cdp, info.s).then((r) => r !== null ? "clicked" : "cant-click");
|
|
306
|
+
}
|
|
307
|
+
if (info.t === "xy") {
|
|
308
|
+
if (!info.x && !info.y)
|
|
309
|
+
return Promise.resolve("cant-click");
|
|
310
|
+
process.stderr.write(`[greedysearch] Human-clicking at (${info.x.toFixed(0)}, ${info.y.toFixed(0)})...
|
|
311
|
+
`);
|
|
312
|
+
return humanClickXY(tab, cdp, info.x, info.y).then(() => "clicked");
|
|
313
|
+
}
|
|
314
|
+
} catch {}
|
|
315
|
+
return Promise.resolve("no-challenge");
|
|
316
|
+
}
|
|
317
|
+
export async function detectVerificationChallenge(tab, cdp) {
|
|
318
|
+
const result = await cdp(["eval", tab, VERIFY_DETECT_JS]).catch(() => null);
|
|
319
|
+
if (result === "cf-closed-shadow-dom") {
|
|
320
|
+
const cfIframe = await findCloudflareIframeViaPierce(tab, cdp).catch(() => null);
|
|
321
|
+
if (cfIframe)
|
|
322
|
+
return cfIframe;
|
|
323
|
+
return result;
|
|
324
|
+
}
|
|
325
|
+
if (result && result !== "null")
|
|
326
|
+
return result;
|
|
327
|
+
return null;
|
|
328
|
+
}
|
|
329
|
+
async function findCloudflareIframeViaPierce(tab, cdp) {
|
|
330
|
+
if (typeof cdp !== "function")
|
|
331
|
+
return null;
|
|
332
|
+
await cdp(["evalraw", tab, "DOM.enable", "{}"]).catch(() => {});
|
|
333
|
+
const doc = await cdp(["evalraw", tab, "DOM.getDocument", JSON.stringify({ depth: -1, pierce: true })]).catch(() => null);
|
|
334
|
+
if (!doc)
|
|
335
|
+
return null;
|
|
336
|
+
let docParsed;
|
|
337
|
+
try {
|
|
338
|
+
docParsed = JSON.parse(doc);
|
|
339
|
+
} catch {
|
|
340
|
+
return null;
|
|
341
|
+
}
|
|
342
|
+
if (docParsed.error || !docParsed.root)
|
|
343
|
+
return null;
|
|
344
|
+
const root = docParsed.root;
|
|
345
|
+
const found = await walkForCfIframe(root, tab, cdp);
|
|
346
|
+
return found;
|
|
347
|
+
}
|
|
348
|
+
async function walkForCfIframe(node, tab, cdp) {
|
|
349
|
+
if (!node)
|
|
350
|
+
return null;
|
|
351
|
+
const children = [];
|
|
352
|
+
if (node.shadowRoots && node.shadowRoots.length > 0) {
|
|
353
|
+
for (const s of node.shadowRoots) {
|
|
354
|
+
children.push(s);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
if (node.children) {
|
|
358
|
+
for (const c of node.children)
|
|
359
|
+
children.push(c);
|
|
360
|
+
}
|
|
361
|
+
for (const child of children) {
|
|
362
|
+
if (child.nodeName === "IFRAME") {
|
|
363
|
+
const attrs = child.attributes || [];
|
|
364
|
+
const srcIdx = attrs.indexOf("src");
|
|
365
|
+
const src = srcIdx >= 0 ? attrs[srcIdx + 1] : "";
|
|
366
|
+
if (src && /challenges\.cloudflare\.com|turnstile/i.test(src) && child.backendNodeId) {
|
|
367
|
+
const boxRes = await cdp([
|
|
368
|
+
"evalraw",
|
|
369
|
+
tab,
|
|
370
|
+
"DOM.getBoxModel",
|
|
371
|
+
JSON.stringify({ backendNodeId: child.backendNodeId })
|
|
372
|
+
]).catch(() => null);
|
|
373
|
+
if (!boxRes)
|
|
374
|
+
continue;
|
|
375
|
+
let boxParsed;
|
|
376
|
+
try {
|
|
377
|
+
boxParsed = JSON.parse(boxRes);
|
|
378
|
+
} catch {
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
381
|
+
const content = boxParsed?.model?.content || boxParsed?.result?.model?.content;
|
|
382
|
+
if (!content || content.length < 8)
|
|
383
|
+
continue;
|
|
384
|
+
const x1 = content[0];
|
|
385
|
+
const y1 = content[1];
|
|
386
|
+
const x3 = content[4];
|
|
387
|
+
const y3 = content[5];
|
|
388
|
+
const width = x3 - x1;
|
|
389
|
+
const height = y3 - y1;
|
|
390
|
+
if (width < 50 || height < 20)
|
|
391
|
+
continue;
|
|
392
|
+
const checkboxX = x1 + width * 0.25;
|
|
393
|
+
const checkboxY = y1 + height * 0.5;
|
|
394
|
+
process.stderr.write(`[greedysearch] Found CF iframe via CDP pierce at (${x1.toFixed(0)}, ${y1.toFixed(0)}) ${width.toFixed(0)}x${height.toFixed(0)}, clicking checkbox at (${checkboxX.toFixed(0)}, ${checkboxY.toFixed(0)})
|
|
395
|
+
`);
|
|
396
|
+
return JSON.stringify({ t: "xy", x: checkboxX, y: checkboxY });
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
const deeper = await walkForCfIframe(child, tab, cdp);
|
|
400
|
+
if (deeper)
|
|
401
|
+
return deeper;
|
|
402
|
+
}
|
|
403
|
+
return null;
|
|
404
|
+
}
|
|
405
|
+
export async function handleVerification(tab, cdp, waitMs = 30000) {
|
|
406
|
+
const result = await detectVerificationChallenge(tab, cdp);
|
|
407
|
+
if (!result)
|
|
408
|
+
return "clear";
|
|
409
|
+
if (result === "sorry-page") {
|
|
410
|
+
process.stderr.write(`[greedysearch] Google CAPTCHA detected — please solve it in the browser window (waiting up to ${Math.floor(waitMs / 1000)}s)...
|
|
411
|
+
`);
|
|
412
|
+
const deadline = Date.now() + waitMs;
|
|
413
|
+
while (Date.now() < deadline) {
|
|
414
|
+
await new Promise((r) => setTimeout(r, 2000));
|
|
415
|
+
const url = await cdp(["eval", tab, "document.location.href"]).catch(() => "");
|
|
416
|
+
if (!url.includes("/sorry/"))
|
|
417
|
+
return "cleared-by-user";
|
|
418
|
+
}
|
|
419
|
+
return "needs-human";
|
|
420
|
+
}
|
|
421
|
+
const clickResult = await tryHumanClick(tab, cdp, result);
|
|
422
|
+
if (clickResult === "clicked") {
|
|
423
|
+
await new Promise((r) => setTimeout(r, 2000));
|
|
424
|
+
const deadline = Date.now() + waitMs;
|
|
425
|
+
while (Date.now() < deadline) {
|
|
426
|
+
const retryResult = await cdp(["eval", tab, VERIFY_RETRY_JS]).catch(() => null);
|
|
427
|
+
if (retryResult === "cleared" || !retryResult || retryResult === "null") {
|
|
428
|
+
process.stderr.write(`[greedysearch] Verification cleared.
|
|
429
|
+
`);
|
|
430
|
+
return "clicked";
|
|
431
|
+
}
|
|
432
|
+
if (retryResult !== "still-verifying") {
|
|
433
|
+
await tryHumanClick(tab, cdp, retryResult);
|
|
434
|
+
await new Promise((r) => setTimeout(r, 2000));
|
|
435
|
+
} else {
|
|
436
|
+
await new Promise((r) => setTimeout(r, 1500));
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
process.stderr.write(`[greedysearch] Verification may require manual intervention.
|
|
440
|
+
`);
|
|
441
|
+
return "needs-human";
|
|
442
|
+
}
|
|
443
|
+
if (clickResult === "cant-click") {
|
|
444
|
+
process.stderr.write(`[greedysearch] Verification challenge detected but cannot be auto-clicked — please solve it manually in the visible browser window.
|
|
445
|
+
`);
|
|
446
|
+
return "needs-human";
|
|
447
|
+
}
|
|
448
|
+
return "clear";
|
|
449
|
+
}
|