Skip to main content

deva-cloak

Drive CloakBrowser stealth Chromium inside the deva cloak container - a headed, anti-detection browser for scraping, automation, or checking a site the way a real browser sees it. Use when the task needs a browser that bypasses bot detection (Cloudflare, FingerprintJS, reCAPTCHA scoring), or when the user asks to browse/scrape a protected site from inside deva. Only applies in the cloak image (verify with `command -v cloakbrowser`; DEVA_CLOAK=1 is the marker); the base/rust images have plain Playwright instead.

Informations de source

Dépôt
thevibeworks/deva
Dernière activité de la source
27 juillet 2026 à 09:32
Langue détectée de SKILL.md
anglais
Étoiles
13
Forks
4

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
deva-cloak
description
Drive CloakBrowser stealth Chromium inside the deva cloak container - a headed, anti-detection browser for scraping, automation, or checking a site the way a real browser sees it. Use when the task needs a browser that bypasses bot detection (Cloudflare, FingerprintJS, reCAPTCHA scoring), or when the user asks to browse/scrape a protected site from inside deva. Only applies in the cloak image (verify with `command -v cloakbrowser`; DEVA_CLOAK=1 is the marker); the base/rust images have plain Playwright instead.
# deva-cloak: stealth browser in the deva cloak container CloakBrowser is a custom-compiled Chromium with source-level fingerprint patches. Same Playwright API, different binary -- detection sites score it as a real browser because it is one. This image runs it **headed by default** on a virtual display, which passes checks that headless fails even with the patches. ## Am I in the cloak context? This skill only applies when the browser is actually present. ALWAYS run this check fresh -- never conclude from conversation context, a resumed session, or `$DEVA_CLOAK` alone (env markers can be scrubbed or stale; the binary is the ground truth): ```bash command -v cloakbrowser >/dev/null && cloakbrowser info --quick ``` If that fails, you are in the base or rust image -- there is no CloakBrowser here. (`DEVA_CLOAK=1` is baked into the cloak image as a convenience marker, but treat it as a hint, not the test.) Tell the user to relaunch with `deva.sh -p cloak <agent>`, or use the plain Playwright install (rust image) instead. Do not try to `npm install cloakbrowser` yourself; the binary is baked into the cloak image and a runtime install would download ~200MB and defeat the point. ## What is baked in - Wrapper + `playwright-core` live in `$CLOAK_APP_DIR` (`/opt/cloak`). - Chromium binary is pre-downloaded, cache at `/opt/cloakbrowser`, auto-update off -- fully offline, no network needed to launch. - Free binary = **Chromium 146** (58 fingerprint patches). No Pro license. Good enough for most sites and for viewing your own apps; the newest detection tricks (latest Cloudflare/DataDome) may still win. Pro (146->150, 71 patches) needs `CLOAKBROWSER_LICENSE_KEY` at runtime -- no rebuild. - Headed display: Xvfb on `:99` + openbox, started by the entrypoint. - `x11vnc` for VNC into that display (interactive logins). Start it on demand (`x11vnc -display :99 -rfbport 5900 -bg`); on OrbStack/Linux the Mac reaches it directly at the container IP -- no port publish, no launch flag. - `cloak-browserd` always-on browser daemon (`/usr/local/lib/cloak/cloak-browserd.mjs`); OPT-IN, runs only with `--cloak-browser`, exposes CDP at `CLOAK_CDP_ENDPOINT`. Independent of VNC. ## Running a script CloakBrowser is ESM-only, so run the script **from `$CLOAK_APP_DIR`** where its `node_modules` resolves. Write output to absolute workspace paths. ```bash cd "$CLOAK_APP_DIR" node --input-type=module <<'EOF' import { launch } from 'cloakbrowser'; // Headed is the whole point of this image -- keep headless:false for // detection-heavy sites. Flip to true only for speed on trusted targets. const browser = await launch({ headless: false }); const page = await browser.newPage(); await page.goto('https://example.com', { waitUntil: 'domcontentloaded' }); console.log(await page.title()); await browser.close(); EOF ``` The returned object is a normal Playwright `Browser` -- `newPage`, `newContext`, `screenshot`, etc. all work unchanged. ## Options that matter Pass to `launch({ ... })`: - `headless: false` -- default posture here; some sites detect headless even with the C++ patches. - `humanize: true` -- human-like mouse curves, per-char typing, scroll. Turn on for behavioral detection (deviceandbrowserinfo, reCAPTCHA v3 scoring). - `proxy: 'http://user:pass@host:port'` or `'socks5://...'` -- residential IPs pass reputation checks that datacenter IPs fail. Add `geoip: true` to match timezone/locale to the proxy exit IP. - `args: ['--fingerprint=12345']` -- fixed seed = a consistent returning-visitor identity across runs (better for reCAPTCHA v3 than a fresh identity each time). Recommended stack for a hard anti-bot target: `launch({ headless: false, humanize: true, proxy: '<residential>', geoip: true })`. ## Authenticated sites: log in over VNC You cannot copy the host browser's cookie DB in -- Chrome encrypts cookie values with an OS-keychain key the Linux container can't reach, so the blobs are undecryptable here. Instead the human logs in once over VNC, watching a browser YOU (the agent) drive on the cloak display -- same browser, same profile, persisted to the host. **The human launches normally -- no VNC flag needed on OrbStack/Linux:** ```bash deva.sh -p cloak claude ``` **You (the agent) start VNC on demand when a login is needed.** OrbStack (and native Linux Docker) route the container straight from the host, so a server you start INSIDE the container is reachable from the Mac with no port publish and no launch flag: ```bash x11vnc -display :99 -rfbport 5900 -forever -shared -bg # add -passwd <pw> to require a password ``` Then tell the human how to connect. The container is reachable from the Mac at its OrbStack address -- `orb list` on the Mac gives the name/IP, then `open vnc://<container-ip>:5900` (or `<name>.orb.local:5900`), built-in Screen Sharing. No `-p`, no recreate. (`--cloak-vnc` still exists, but only for plain Docker Desktop, where the container IP is NOT routable from the host and a published loopback port is the only way in. On OrbStack you don't need it -- and it does not have to be set at launch.) **You (the agent) open a headed browser on the display and drive it.** Use a persistent context on the mounted profile so the login survives: ```bash cd "$CLOAK_APP_DIR" node --input-type=module <<'EOF' import { launchPersistentContext } from 'cloakbrowser'; const ctx = await launchPersistentContext({ userDataDir: process.env.DEVA_CLOAK_PROFILE_DIR || '/home/deva/.cloak-profile', headless: false, // renders on :99 so the human sees it over VNC }); const page = ctx.pages()[0] || await ctx.newPage(); await page.goto('https://SITE/login'); // Tell the human: open the printed vnc:// URL and log in (MFA/captcha). // Wait for the post-login page, then continue -- you hold the same context. await page.waitForURL('**/app**', { timeout: 300000 }); console.log('logged in:', await page.title()); await ctx.close(); // profile saved to the mounted host dir EOF ``` The human opens `vnc://127.0.0.1:PORT` (macOS: `open vnc://127.0.0.1:5901`, built-in Screen Sharing), sees your browser, and logs in. Because you hold the same persistent context, the session is yours immediately and -- via the mounted profile -- survives to the next run, even headless with no VNC. **Optional: always-on shared daemon (`--cloak-browser`).** For a browser that stays up across agent runs (so the human can log in even when no agent is active), launch with `--cloak-browser`. deva starts one persistent headed browser and sets `CLOAK_CDP_ENDPOINT`; attach to it instead of launching your own -- do NOT `launch()` a second browser, it would miss the login: ```bash import pw from 'playwright-core'; const b = await pw.chromium.connectOverCDP(process.env.CLOAK_CDP_ENDPOINT); const ctx = b.contexts()[0]; // the daemon's profile, NOT b.newContext() const page = ctx.pages()[0] || await ctx.newPage(); await page.goto('https://SITE/app'); // already logged in await b.close(); // detaches; the daemon browser stays up ``` `CLOAK_CDP_ENDPOINT` is set only when the daemon runs (`--cloak-browser`); its absence means there is no daemon and you should launch your own browser as above. Use `goto()`, not `setContent()`: on a fresh daemon page `setContent` waits for a `load` event that never fires and times out. `page.goto('data:text/html,...', {waitUntil: 'domcontentloaded'})` is the working equivalent for injected markup. **Persistence / what to mount.** `--cloak-vnc` (and `--cloak-browser`) auto-mounts `~/.config/deva/cloak-profile` (host) to the Chromium `userDataDir` `/home/deva/.cloak-profile`. That one dir is the whole session -- cookies, localStorage, IndexedDB, service workers, Cache, History, Login Data. It survives container removal, so a login done once is reused by every later run (even headless, no VNC). Override the host location with `DEVA_CLOAK_PROFILE_DIR=/path deva.sh -p cloak --cloak-vnc ...`, or mount your own dir at `/home/deva/.cloak-profile` (your mount wins). Do NOT mount `/opt/cloakbrowser` -- that is the baked binary, not session data. Gotcha: only cookies with an `expires` survive a profile reopen -- session cookies (no expiry) are memory-only. Real logins persist via the site's long-lived "remember me" / refresh-token cookie, which carries an expiry, so genuine sessions survive (verified). **storageState alternative** (no daemon/VNC): if you captured Playwright storage state elsewhere (cookies + localStorage as plaintext JSON) and mounted the file, load it into a one-off context -- note the nesting: ```bash node --input-type=module <<'EOF' import { launchContext } from 'cloakbrowser'; // storageState MUST be under contextOptions -- launchContext feeds it to // newContext(). Top-level storageState is silently dropped and you get an // UNauthenticated browser (verified against cloakbrowser 0.4.x). const ctx = await launchContext({ headless: false, contextOptions: { storageState: '/home/deva/.cloak-auth/SITE.json' } }); const page = await ctx.newPage(); await page.goto('https://SITE/app'); await ctx.close(); EOF ``` SECURITY -- the profile dir (and any storage-state file) is a live bearer credential: whoever holds it holds the session. This container runs the agent with permissions disabled. VNC is auto-passworded; keep it that way. Only keep the single site the task needs, and never print, log, copy, or write these files back to a shared/primary account. Treat them as secrets. ## CLI (no script needed) ```bash cloakbrowser info # what binary launches, license tier, env checks cloakbrowser info --quick # skip the launch test ``` ## Gotchas - Bare `import 'cloakbrowser'` only resolves when cwd is `$CLOAK_APP_DIR` (Node ESM resolves bare specifiers from cwd for `--input-type=module`). From elsewhere, import the absolute path: `import(process.env.CLOAK_APP_DIR + '/node_modules/cloakbrowser/dist/index.js')`. - Do not run `npx cloakbrowser ...` -- the wrapper is not global; use the `cloakbrowser` command (symlinked) or the `$CLOAK_APP_DIR` binary. - For reCAPTCHA scoring, use native `setTimeout`, not `page.waitForTimeout()` (the latter sends CDP traffic reCAPTCHA detects); use `page.type()` not `page.fill()` so keystroke events fire. - CloakBrowser prevents CAPTCHAs; it does not solve them. Bring your own proxy.
Voir sur GitHub