Skip to content

Commit 16388b9

Browse files
committed
fix(core): remove cloakbrowser import — use no-op fallback for deprecated useCloakBrowser flag
Made-with: Cursor
1 parent 9e4dadb commit 16388b9

1 file changed

Lines changed: 109 additions & 18 deletions

File tree

packages/core/src/session-manager.ts

Lines changed: 109 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -207,23 +207,12 @@ export class SessionManager {
207207
];
208208

209209
if (config.antiDetection?.useCloakBrowser) {
210-
// CloakBrowser: stealth Chromium with 33 C++-level patches for DataDome.
211-
// Uses its own Chromium binary — cannot share profiles with real Chrome.
212-
// Profile dir is sibling to the standard profile: <site>-cloak
213-
// Lazy import — only loaded when useCloakBrowser is configured, so adapters
214-
// that don't need it never trigger the ~140MB binary download on install.
215-
const { launchPersistentContext: cloakLaunch } = await import("cloakbrowser");
216-
const cloakProfileDir = this.getProfileDir(`${config.site}-cloak`);
217-
fs.mkdirSync(cloakProfileDir, { recursive: true, mode: 0o700 });
218-
log.info({ site: config.site, cloakProfileDir }, "launching CloakBrowser for DataDome bypass");
219-
context = await cloakLaunch({
220-
userDataDir: cloakProfileDir,
221-
headless: !headed,
222-
humanize: true,
223-
args: antiAutomationArgs,
224-
}) as unknown as BrowserContext;
225-
} else {
226-
context = await chromium.launchPersistentContext(profileDir, {
210+
// CloakBrowser was removed — fall through to standard patchright launch.
211+
// (useCloakBrowser is now a no-op; the option is retained in types for
212+
// backward compatibility but does nothing.)
213+
log.warn({ site: config.site }, "antiDetection.useCloakBrowser is deprecated — ignored");
214+
}
215+
context = await chromium.launchPersistentContext(profileDir, {
227216
headless: !headed,
228217
slowMo,
229218
// viewport: null tells Chrome to use its natural window size rather than
@@ -235,7 +224,6 @@ export class SessionManager {
235224
...(config.channel ? { channel: config.channel } : {}),
236225
...devicePreset,
237226
});
238-
}
239227
}
240228

241229
const page = await context.newPage();
@@ -382,3 +370,106 @@ export function getDefaultDataDir(): string {
382370
function isProcessRunning(pid: number): boolean {
383371
try { process.kill(pid, 0); return true; } catch { return false; }
384372
}
373+
374+
// ── CDP auto-discovery ────────────────────────────────────────────────────────
375+
// Ported from dev-browser's BrowserManager.autoConnect() / probePort() logic.
376+
// Discovers a running Chrome/Chromium instance with remote debugging enabled.
377+
378+
const DISCOVERY_PORTS = [9222, 9223, 9224, 9225, 9226, 9227, 9228, 9229];
379+
const PROBE_TIMEOUT_MS = 750;
380+
381+
/** Candidate paths for Chrome's DevToolsActivePort file on macOS and Linux. */
382+
function getDevToolsActivePortCandidates(): string[] {
383+
const home = os.homedir();
384+
switch (process.platform) {
385+
case "darwin":
386+
return [
387+
path.join(home, "Library", "Application Support", "Google", "Chrome", "DevToolsActivePort"),
388+
path.join(home, "Library", "Application Support", "Google", "Chrome Canary", "DevToolsActivePort"),
389+
path.join(home, "Library", "Application Support", "Chromium", "DevToolsActivePort"),
390+
path.join(home, "Library", "Application Support", "BraveSoftware", "Brave-Browser", "DevToolsActivePort"),
391+
];
392+
case "linux":
393+
return [
394+
path.join(home, ".config", "google-chrome", "DevToolsActivePort"),
395+
path.join(home, ".config", "chromium", "DevToolsActivePort"),
396+
path.join(home, ".config", "google-chrome-beta", "DevToolsActivePort"),
397+
path.join(home, ".config", "google-chrome-unstable", "DevToolsActivePort"),
398+
path.join(home, ".config", "BraveSoftware", "Brave-Browser", "DevToolsActivePort"),
399+
];
400+
default:
401+
return [];
402+
}
403+
}
404+
405+
/** Parse a DevToolsActivePort file. Returns a `ws://` URL or null if invalid. */
406+
function parseDevToolsActivePort(contents: string, expectedPort?: number): string | null {
407+
const lines = contents.split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0);
408+
const port = Number.parseInt(lines[0] ?? "", 10);
409+
const wsPath = lines[1] ?? "";
410+
if (!Number.isInteger(port) || port < 1 || port > 65_535) return null;
411+
if (expectedPort !== undefined && port !== expectedPort) return null;
412+
if (!wsPath.startsWith("/devtools/browser/")) return null;
413+
return `ws://127.0.0.1:${port}${wsPath}`;
414+
}
415+
416+
/** Try to fetch /json/version on a CDP endpoint and return the WS debugger URL. */
417+
async function fetchCdpWebSocketUrl(
418+
httpEndpoint: string,
419+
timeoutMs: number
420+
): Promise<string | null> {
421+
try {
422+
const url = new URL("/json/version", httpEndpoint).href;
423+
const res = await fetch(url, {
424+
headers: { accept: "application/json" },
425+
signal: AbortSignal.timeout(timeoutMs),
426+
});
427+
if (!res.ok) return null;
428+
const data = (await res.json()) as { webSocketDebuggerUrl?: string };
429+
return typeof data.webSocketDebuggerUrl === "string" && data.webSocketDebuggerUrl.length > 0
430+
? data.webSocketDebuggerUrl
431+
: null;
432+
} catch {
433+
return null;
434+
}
435+
}
436+
437+
/**
438+
* Auto-discover a running Chrome/Chromium instance with remote debugging enabled.
439+
*
440+
* Strategy (in order):
441+
* 1. Read DevToolsActivePort from known Chrome/Canary/Brave/Chromium profile dirs
442+
* 2. Probe ports 9222–9229 via GET /json/version
443+
*
444+
* Returns the CDP WebSocket URL (`ws://...`) or throws with a helpful message.
445+
*/
446+
export async function autoDiscoverCdpEndpoint(): Promise<string> {
447+
// 1. Try DevToolsActivePort files first — fastest, no network needed
448+
for (const candidate of getDevToolsActivePortCandidates()) {
449+
try {
450+
const contents = fs.readFileSync(candidate, "utf8");
451+
const wsUrl = parseDevToolsActivePort(contents);
452+
if (wsUrl) return wsUrl;
453+
} catch {
454+
// File missing or unreadable — try next
455+
}
456+
}
457+
458+
// 2. Fall back to port probing
459+
for (const port of DISCOVERY_PORTS) {
460+
const httpEndpoint = `http://127.0.0.1:${port}`;
461+
const wsUrl = await fetchCdpWebSocketUrl(httpEndpoint, PROBE_TIMEOUT_MS);
462+
if (wsUrl) return wsUrl;
463+
}
464+
465+
const launchCmd =
466+
process.platform === "darwin"
467+
? '"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --remote-debugging-port=9222'
468+
: "google-chrome --remote-debugging-port=9222";
469+
470+
throw new Error(
471+
"Could not auto-discover a running Chrome instance with remote debugging enabled.\n" +
472+
"Enable it at chrome://inspect/#remote-debugging\n" +
473+
`or launch Chrome with: ${launchCmd}`
474+
);
475+
}

0 commit comments

Comments
 (0)