Files
claw-apply/lib/browser.mjs
Claw 52a56f59f6 feat: claw-apply v0.1 — full implementation
- job_searcher.mjs: LinkedIn + Wellfound search, queue population
- job_applier.mjs: Easy Apply + Wellfound apply, Mode A/B
- lib/form_filler.mjs: config-driven form filling, custom answers.json
- lib/linkedin.mjs: two-panel Easy Apply flow
- lib/wellfound.mjs: Wellfound search + apply
- lib/browser.mjs: Kernel stealth browser factory with local fallback
- lib/queue.mjs: jobs_queue.json management
- lib/notify.mjs: Telegram notifications
- setup.mjs: setup wizard with login verification
- Config templates: profile, search_config, answers, settings
- SKILL.md: OpenClaw skill definition
2026-03-05 23:24:09 +00:00

67 lines
2.2 KiB
JavaScript

/**
* browser.mjs — Browser factory
* Creates Kernel stealth browsers or falls back to local Playwright
*/
import { chromium } from 'playwright';
export async function createBrowser(settings, profileKey) {
const { provider, playwright_path } = settings.browser || {};
const kernelConfig = settings.kernel || {};
if (provider === 'local') {
return createLocalBrowser();
}
// Default: Kernel
try {
return await createKernelBrowser(kernelConfig, profileKey);
} catch (e) {
console.warn(`[browser] Kernel failed (${e.message}), falling back to local`);
return createLocalBrowser();
}
}
async function createKernelBrowser(kernelConfig, profileKey) {
// Dynamic import so it doesn't crash if not installed
let Kernel;
try {
const mod = await import('@onkernel/sdk');
Kernel = mod.default;
} catch {
throw new Error('Kernel SDK not installed — run: npm install @onkernel/sdk');
}
if (!process.env.KERNEL_API_KEY) throw new Error('KERNEL_API_KEY not set');
const kernel = new Kernel({ apiKey: process.env.KERNEL_API_KEY });
const profileName = kernelConfig.profiles?.[profileKey];
if (!profileName) throw new Error(`No Kernel profile configured for "${profileKey}"`);
const opts = { stealth: true, profile: { name: profileName } };
if (kernelConfig.proxy_id) opts.proxy = { id: kernelConfig.proxy_id };
const kb = await kernel.browsers.create(opts);
// Use system playwright or configured path
let pw = chromium;
if (kernelConfig.playwright_path) {
const mod = await import(kernelConfig.playwright_path);
pw = mod.chromium;
}
const browser = await pw.connectOverCDP(kb.cdp_ws_url);
const ctx = browser.contexts()[0] || await browser.newContext();
const page = ctx.pages()[0] || await ctx.newPage();
return { browser, page, type: 'kernel' };
}
async function createLocalBrowser() {
const browser = await chromium.launch({ headless: true });
const ctx = await browser.newContext({
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36'
});
const page = await ctx.newPage();
return { browser, page, type: 'local' };
}