{
  "markdown": "<!-- Absolute URL on purpose: PyPI renders this same README and cannot resolve\n     repo-relative paths. Pinned to master so it survives tag churn. -->\n<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/trueoriginlabs/vibatchium/master/assets/vb-logo.png\" alt=\"vibatchium\" width=\"180\">\n</p>\n\n# vibatchium\n\n<!-- mcp-name: io.github.trueoriginlabs/vibatchium -->\n\n**Agent-piloted browser automation that clears Cloudflare.**\nPatched Playwright + multi-session daemon + credential vault + vision clicking + prompt-injection safety. One MCP server, N parallel Chromes, persistent per-session profiles.\nPlus two renderer-free lanes on a Chrome TLS fingerprint: **`vb search`** to find\nURLs without a search API, **`vb fetch`** to read them — both with per-request\n`--proxy`, because engines and walls both rate-limit per IP.\n\n> **Where this fits.** Both Anthropic and Google now ship an agent that drives\n> *your own* signed-in Chrome — Claude in Chrome and Chrome Auto Browse. If that\n> is what you want, use them: they are free, first-party, and better integrated.\n> They are also **supervised** — visible window, real time, and they hand control\n> back to you at a login wall or a CAPTCHA. vibatchium is for the other half:\n> **unattended, headless, N-at-a-time**, on a box with no human in front of it,\n> against sites that fight automation. That is the whole of the wedge, and it is\n> worth being precise about which side of it you are on.\n\n```\npipx install vibatchium             # core: browse / extract / screenshot / N parallel sessions\n# want the stealth HTTP lanes (vb fetch, vb search), the credential vault, VLM read, or the REST shim?\npipx install 'vibatchium[all]'      # everything; or pick extras: vibatchium[fetch], [secrets], [llm], [rest]\npatchright install chrome\nvb setup                    # register MCP + an auto-discoverable skill so agents reach for vb (idempotent)\n```\n\nCore install covers all browsing. `vb fetch` and `vb search` (the curl_cffi\nTLS-fingerprint lane) are the `[fetch]` extra; `vb install` reports which optional lanes are available. On a **uv** venv\n(no pip), add an extra with `uv pip install --python <venv>/bin/python curl_cffi`.\n\n> Bleeding edge from `master`: `pipx install 'git+https://github.com/trueoriginlabs/vibatchium#egg=vibatchium[all]'`\n\n> **Coding agents (Codex / Cursor / Claude Code):** read [`AGENTS.md`](AGENTS.md) first — it has the one-call recipes (`explore`, `research`) and the env-discovery traps to skip.\n\n```\nvb explore https://example.com                      # one-call: text-first (screenshot only as a fallback)\nvb research --target https://example.com \\          # parallel fan-out, N intents\n  --intent \"pricing model\" --intent \"customers\" --intent \"tech stack\"\n```\n\n**Status:** active development, alpha. **1,195 tests** green in CI (Linux, Python 3.11–3.13). Apache-2.0 (AGPL only via the opt-in `nodriver` extra).\n\n<sub>Detector scores quoted below (bot.sannysoft, CreepJS, Cloudflare cold-launch) are **manual observations, not CI-asserted** — no test in the suite gates on them, and they are only as current as the last hand-run. The generated block under [Measured scores](#measured-scores) is the one to trust; it is empty until someone runs it.</sub>\n\n## Updating\n\n```bash\nvb update                  # upgrade + bounce the daemon + refresh the agent skill\nvb update --version 0.19.0   # or pin a specific version\n```\n\n`vb update` detects how vibatchium was installed (pipx, `uv tool install`,\na pip-less uv venv, or pip with a PEP-668 `--break-system-packages` fallback),\n**stops the running daemon** so the next command loads the new code, and\n**rewrites the agent skill / docs blocks** so a coding agent is actually told\nabout the verbs the new version ships (`--no-restart` / `--no-setup` opt out).\nManual equivalent:\n\n```bash\npipx upgrade vibatchium    # or: uv tool upgrade vibatchium / pip install -U vibatchium\nvb shutdown                # bounce the daemon — it serves old code until you do\nvb setup                   # refresh the agent skill + docs\nvb --version               # confirm\n```\n\n> The daemon-restart step is the one people miss: the long-running daemon keeps\n> serving the **old** version until it's bounced. `vb update` does it for you;\n> if you upgrade by hand, run `vb shutdown` (the next `vb` call auto-respawns the\n> new version). Optional features upgrade via `pipx install 'vibatchium[all]' --force`.\n\n### Running from a git checkout\n\n`git pull` updates the **source**; whether it updates what `vb` actually runs\ndepends on the install, and two of the three ways it can fail are silent:\n\n```bash\nvb --version && git describe --tags   # do they agree? if not, the install COPIED\n                                      # the source — reinstall editable:\n                                      #   uv pip install -e '.[all]'\nvb status                             # warns when the daemon predates the source\n                                      # (\"stale_code\") — bounce with `vb shutdown`\n```\n\nA version-string compare cannot catch a checkout: `git pull` changes the code\nwithout changing `__version__`. `vb status` compares the daemon's boot time\nagainst the newest source file instead, and `vb update` bounces the daemon only\nwhen it is provably behind — so it never drops live sessions for nothing.\n\n### New cap buckets need a re-register\n\nThe MCP server's `--caps` list is frozen into your agent's config at first\nregistration, so a bucket added by a later release (0.19.0 added `search`) stays\ninvisible no matter how many times you upgrade. Re-running `vb setup` reports\nthe drift but deliberately won't overwrite a `--caps` you set by hand:\n\n```bash\nvb setup                              # reports any cap drift, changes nothing\nvb setup --force --caps lean,search   # apply it — exposes `vb search` as a tool\n```\n\nRestart the agent session afterwards: the MCP tool list is read once, at start.\n\n## Why vibatchium\n\nPersistent logged-in profiles, credential vaults, CDP-attach, N named sessions —\n[agent-browser][ab] and [playwright-mcp][pmcp] all ship those now, at download\nvolumes we won't match. A comparison table winning rows nobody contests was\nnoise; it's gone.\n\nWhat's still ours: **stealth patches in core** (agent-browser's stealth issue has\nbeen open since Jan 2026 and the PR attempting it was closed), **prompt-injection\nscanning on by default** for page content (nobody else in this lane ships it —\nthough it does not yet cover the `fetch`/`search` lanes), **TOTP + IMAP 2FA**\nso an unattended run survives a login challenge, and the combination that only\nmatters together — real stock Chrome + CDP stealth + headless + *unattended* + N\npersistent logins, on your own machine.\n\nIf you don't need the stealth half, use one of the above. They're bigger, older\nand better tested than we are.\n\n[ab]: https://github.com/vercel-labs/agent-browser\n[pmcp]: https://github.com/microsoft/playwright-mcp\n\n## Real Chrome vs fake Chrome\n\nA wave of \"headless browser for AI agents\" tools rebuild the browser from scratch\n(Rust + V8, no Blink/Skia) to hit tiny memory and sub-100ms page loads. The catch\nis structural: **with no rendering engine, they can't produce a real device's\nfingerprint — they synthesize one.** And synthetic fingerprints don't hold still.\n\nvibatchium drives *real* Google Chrome, so its fingerprints are real — and, more\nto the point, **stable**. The single test that separates the two is fingerprint\nstability across navigations. Run the same canvas + WebGL probe on two pages in\none session:\n\n| | vibatchium (real Chrome) | synthesized-fingerprint engines |\n|---|---|---|\n| canvas hash, page A → page B | **identical** | reseeded per navigation |\n| WebGL `readPixels` | real, **deterministic** pixels | often `Math.random()` |\n| WebGL renderer | a real ANGLE renderer¹ | stub / zeros |\n\n<sub>¹ Chrome's own software renderer (SwiftShader) by default — still a coherent, deterministic Chrome value, not a stub. A hardware-GPU string (e.g. `ANGLE (Intel …)`) needs the opt-in `--gpu` flag.</sub>\n\nA real device returns the same fingerprint every page load; a fingerprint keyed\noff `Date.now()` does not — and *that inconsistency* is exactly what lie-detection\nfingerprinters (CreepJS and friends) flag. Measured: vibatchium's canvas hash and\nWebGL readback are byte-identical across navigations, and CreepJS reported **0 %\nstealth-tampering** (no synthetic-environment signatures) when last run by hand.\nThat figure is not regression-tested — treat it as an observation, not a guarantee.\n\n**This is not a claim of invisibility.** The moat is fingerprint *authenticity*,\nnot hiding that a browser is automated — vibatchium still reads as headless on the\nheadless-specific tells (see [Honest limits](#honest-limits)), and real-GPU WebGL\n(`--gpu`) is opt-in. But real, consistent fingerprints pass the consistency tier\nthat synthetic ones fail *by construction* — and that tier is what stands between\nyou and a login wall.\n\n## Multi-session in 10 lines\n\n```\nvb session new work\nvb --session work start\nvb --session work go https://github.com           # log in by hand once\nvb session new banking\nvb --session banking start\nvb --session banking go https://bank.example.com\nvb --session work click @e3 &                     # truly parallel —\nvb --session banking fill @e5 hi &                # separate Chromes, no cookie bleed\nwait\nvb session list\n```\n\nActive-session resolution: `--session FLAG` → `$VIBATCHIUM_SESSION` env → `~/.config/vibatchium/active-session` → `default`. Cap via `VIBATCHIUM_MAX_SESSIONS=8` (default 8).\n\n### Multi-agent: shared sessions vs a private daemon\n\nOn **one** shared daemon, sessions give real fingerprint isolation (separate\nChromes, no cookie bleed) but share the host: the session count budget, the\nmemory, and the blast radius of an OOM or a daemon bounce. Two models, pick per\ntrust level:\n\n- **Cooperating agents (your own fleet):** the shared daemon is right — just give\n  each concurrent agent a **unique `--session` name** so stateful flows don't\n  collide on `default`. `vb session lease` coordinates a shared name.\n- **A private blast radius:** a **per-agent daemon** on its own socket + `HOME`\n  — separate profiles/config/state, its own session budget, zero contact with\n  the shared daemon. `vb daemon start --isolated` prints the `XDG_RUNTIME_DIR`/\n  `HOME` to export for subsequent calls; `vb mcp --isolated` runs the MCP server\n  on its own private daemon directly. `vb daemon reap` cleans up abandoned ones.\n  (Same UID = same trust domain — this bounds *blast radius*, not a security\n  boundary between distrusting tenants; for that, separate UIDs/containers.)\n\n**Resource governance.** The session cap bounds process *count*, not bytes. On a\nshared box, set `VIBATCHIUM_SESSION_RAM_FLOOR_MB` to refuse a new launch when free\nmemory is low (a portable admission belt). For a hard ceiling, run the daemon\nunder a cgroup — `systemd-run --user --scope -p MemoryMax=4G vb daemon start` puts\nthe daemon **and all its Chromes** in one cgroup sharing the limit: an *aggregate*\ndaemon-wide cap (not per-renderer), and a breach OOM-kills inside the scope, which\ncan include the daemon. It's the only non-racy memory bound, so size it for the\nwhole fan-out.\n\n**Idle CPU.** Parked sessions can't burn cores either: the daemon SIGSTOPs a\nlaunched session's renderer processes after `VIBATCHIUM_IDLE_FREEZE_AFTER` seconds\nwith no verb (default 90) and thaws them on the next call, so an idle WebGL /\nanimation page drops to zero CPU without a teardown (default on;\n`VIBATCHIUM_IDLE_FREEZE=0` disables).\n\n## Documentation\n\n- [`AGENTS.md`](AGENTS.md) — coding-agent contract (Codex / Cursor / Claude Code)\n\n## Server modes\n\n| Mode | Surface | Auth |\n|---|---|---|\n| `vb mcp` | stdio JSON-RPC; defaults to the **lean** 86-verb profile (`--caps=full`/`all` for the full surface; `--caps=...` for a custom bucket set) | n/a (stdio) |\n| `vb serve` | FastAPI on `127.0.0.1:8000`; every verb at `POST /v1/<verb>`; WebSocket live-view at `/v1/stream/<session>` | bearer token (`~/.cache/vibatchium/rest-token`, mode 0600) |\n\n**REST capability gating**: `vb serve --caps=core,nav,input,vision` restricts the HTTP surface the same way `mcp --caps` does. Without it, REST grants local-code-equivalent access (eval + secret_* + file-writing verbs all exposed) — safe for localhost dev, **not** for hosted/multi-tenant.\n\n## Stealth tiers — what clears what\n\nStealth is a ladder, not a boolean. Pick the lowest tier that clears your target\n(higher tiers cost more setup / a visible browser / a manual login). vibatchium\ndoes **not** claim cold-launch defeat of behavioral walls — those need a real\nhuman-driven session, and attach-mode is the honest answer.\n\n> **Architecture caveat.** Every tier below was measured on **x86-64 Linux**.\n> Patchright has a known open arm64 / Apple-Silicon detection gap, so these\n> results should not be assumed to carry to an ARM host. If you run there,\n> measure before you rely on it.\n\n| Tier | How | Clears | Doesn't clear |\n|---|---|---|---|\n| **Standard** (default) | headless cold launch, real `channel=chrome`, de-Headless'd UA | Cloudflare IUAM / managed challenge, `bot.sannysoft` 31/31, JS-runtime fingerprinting | aggressive Turnstile, DataDome/Kasada, anything behind a login |\n| **Hardened** | retry `--headed`; `vb humanize on`; `--backend nodriver` (`pip install vibatchium[nodriver]`, AGPL) for the hardest Cloudflare gates | aggressive Cloudflare/Turnstile, GPU/screen tells that headless leaves | behavioral biometrics, DataDome/Kasada sensor-fusion |\n| **Attach** | `vb attach` to a Chrome **you** launched and logged into | DataDome / Kasada / HUMAN behavioral walls, and any authenticated session — your real fingerprint + cookies | nothing here is automated cold; it needs the human login first |\n\n### Measured scores\n\n`vb evals run --update-readme` writes measured numbers into the block below, so\nwhat we publish is generated rather than asserted. It is empty until someone\nruns it — an empty block is honest; a number with no run behind it is not.\n\nRun on x86-64 Linux, 25 Aug 2026, Chrome 150, `--gpu` (real render node).\nPass `--gpu` yourself: headless Chrome falls back to SwiftShader when the GPU\npath doesn't take, and software GL is itself a detection signal, so numbers\nmeasured without it are a floor rather than what a GPU-backed deployment gets.\n\n<!-- vibatchium-evals -->\n| Target | Backend | Humanize | GPU | Score | Status | Time |\n|---|---|---|---|---|---|---|\n| sannysoft | patchright | off | real | 100 | OK | 17.78s |\n| creepjs | patchright | off | real | 44 | OK | 7.88s |\n| brotector | patchright | off | real | 10 | OK | 7.13s |\n| sannysoft | nodriver | off | real | 100 | OK | 19.85s |\n| creepjs | nodriver | off | real | 44 | OK | 9.72s |\n| brotector | nodriver | off | real | 10 | OK | 7.73s |\n<!-- /vibatchium-evals -->\n\n**Read these honestly — two of the three are bad.**\n\n- **sannysoft 100** is the floor everyone in this category clears; it is not a\n  differentiator.\n- **creepjs 44** is mediocre. CreepJS is an adversarial *lie-detector*: it\n  cross-checks main-thread against worker-thread claims and grades confidence,\n  so a middling score means our environment is coherent but not indistinguishable.\n- **brotector 10** is poor, and we know exactly why. The signal firing is\n  `UA_Override / HighEntropyValues.empty`, and **our own de-Headless fix causes\n  it.** Measured on Chrome 150, headless, same profile, with and without the\n  `--user-agent` flag we set to strip `HeadlessChrome`:\n\n  | | `architecture` | `bitness` | `uaFullVersion` | UA string |\n  |---|---|---|---|---|\n  | without the flag | `x86` | `64` | `150.0.7871.114` | says **HeadlessChrome** |\n  | with the flag | *empty* | *empty* | *empty* | says **Chrome** |\n\n  Passing an explicit UA makes Chrome stop deriving high-entropy client hints,\n  so we trade a UA-string tell for a UA-CH-emptiness tell. It is not fixed: the\n  obvious repair (`Emulation.setUserAgentOverride` with `userAgentMetadata`) is\n  target-scoped and would reintroduce a main-vs-worker mismatch that is a\n  *stronger* tell than either leak alone. Publishing this rather than dropping\n  the target is the point — a suite that only reports its wins is marketing.\n- **`nodriver` scores identically to `patchright` on all three.** The escalation\n  tier buys nothing measurable *on static scoreboards*; its case rests on the\n  automation-protocol axis these targets don't probe. An earlier run had\n  `nodriver` slightly *ahead* on creepjs (50 vs 44) — but that run silently\n  denied it the GPU while patchright got a real one, so it was scoring from\n  behind. Once both arms get a real renderer the difference disappears.\n\n> **What these do and don't cover.** These are *fingerprint scoreboards* —\n> the static axis. Through 2026 the major anti-bot vendors moved to\n> session-lifetime **behavioural** scoring, which none of these targets\n> measure, and which we have **not** measured against any commercial vendor.\n> Treat a good score here as evidence about environment coherence only.\n\nFor the behavioural axis itself, `vb oracle run` is a self-hosted probe: it drives a\npage with `humanize` off then on and grades trajectory curvature, dwell, keystroke\ncadence and scroll dynamics against a human-plausible band (`vb oracle record`\ncaptures a real-operator baseline; literature defaults until you do). It measures\n*our* model of human rather than a named vendor — but it turns \"we humanize\" into a\nmeasured on/off delta, and it's honest about the one axis synthetic input can't\nreach: CDP input emits no raw-pointer / coalesced events, which only attach-mode\nagainst real hardware closes.\n\nEscalation ladder when a wall trips: **headless → `--headed` → `humanize on` →\n`--backend nodriver` → attach-mode after a manual login.** Patchright's CDP-layer\npatches apply in *all* tiers, including attach (`connect_over_cdp`).\n\n> The `fetch` verb is an orthogonal fast-path, not a tier: once you're past a\n> wall in the browser, `vb fetch` reuses that session's cookies+proxy to hit\n> JSON/API endpoints at TLS-fingerprint-correct speed — but it runs no JS, so it\n> can't *clear* a JS challenge itself.\n\n## Search — find the URL, not just read it\n\nReading a walled page is only half a research loop; the other half is discovery,\nand search engines are anti-bot walled like everything else. `vb search` runs the\nSERP over the same curl_cffi lane — **no browser, no session, no API key, and no\nper-session call budget to run out of mid-run.**\n\n```\nvb search \"playwright stealth detection\" -n 5\nvb search \"cdp leak\" --site github.com -n 20\nvb search \"postmortem\" --urls | xargs -I{} vb fetch --no-cookies {}\n```\n\nEngines are tried as a ladder (`ddg → ddg-lite → bing`) until one answers,\nbecause reachability moves: the endpoint serving results now may rate-limit\n(HTTP 202) on the next call. `--json` returns an `attempts` array naming every\nengine that declined and why, and a `reason` separating *all engines are walled*\nfrom *the web has nothing* — different problems, different fixes, and the CLI\nexits non-zero only for the first.\n\nIt never reuses session cookies (a SERP needs no login, and attaching one\ndeanonymises the request), which is why it gets its own `search` cap instead of\nriding on `fetch`. No date filter is exposed on purpose: DuckDuckGo's mislabels\narticle dates badly enough to corrupt a timeline. Engines rate-limit per IP — see\nproxies, below.\n\n## Proxies — per-request egress on both stealth lanes\n\nEgress is the axis most people get wrong, so it gets stated precisely rather than\nimplied. Both curl_cffi lanes take `--proxy scheme://[user:pass@]host:port`:\n\n```\nvb fetch --no-cookies https://api.example/v1 --proxy http://user:pass@gw:12323\nvb search \"site reliability postmortem\" -n 20 --proxy http://user:pass@gw:12323\nvb --session work proxy set http://user:pass@gw:12323    # or per-session, for the browser\n```\n\nMeasured, not asserted — same box, same command, only `--proxy` differing:\n\n| | egress IP |\n|---|---|\n| direct | `115.70.50.70` |\n| `--proxy` (authenticated gateway) | `212.69.0.85` |\n\nFour things worth knowing:\n\n- **Unset means direct, and that is enforced.** The daemon hands libcurl an\n  explicit empty proxy, which is the only value that stops it reading\n  `HTTP(S)_PROXY` / `ALL_PROXY` out of the environment it was spawned with. A\n  long-lived daemon inherits whatever shell first started it, so without this a\n  stray `HTTPS_PROXY` would silently reroute every request while the response\n  claimed direct egress. (It did, until 0.19.0 — see the changelog.)\n- **It matters most for `search`.** Engines rate-limit *per IP*, so a wide\n  research fan-out from one address is the fastest way to push every query onto\n  the last rung of the engine ladder. The response reports `proxied: true|false`\n  so you can tell which IP a thin result set came from.\n- **The proxy address is SSRF-guarded** like the target URL, with\n  `--allow-internal` to opt in to a proxy on your own LAN. An unguarded proxy\n  reaches internal services and returns their response bodies, not just\n  connection errors.\n- **A bad proxy is an error, never a fallback.** Silently egressing from the host\n  IP when you asked for a specific one is worse than failing, because the whole\n  point of asking was that the host IP must not be used. Proxy URLs are redacted\n  from the verb log; responses carry the boolean, never the URL.\n\nWith a browser session, `vb proxy set` also wires the **WebRTC leak guard** — a\ntunnelled HTTP request still leaks the real IP via STUN without it.\n\n## Attach mode — the practical Cloudflare workaround\n\nFor DataDome / Kasada / hardened auth that walls cold-launch automation:\n\n```\ngoogle-chrome --remote-debugging-port=9222 \\\n              --disable-blink-features=AutomationControlled \\\n              --user-data-dir=/tmp/cdp-profile &\n# log into the walled site by hand\nvb attach http://localhost:9222\nvb go https://target.example.com        # now reads as your real browser\n```\n\nPatchright's CDP-layer stealth still applies over `connect_over_cdp` — attach mode gets the same protocol-level patches as cold launch, plus your real-browser fingerprint and any cookies from the manual login.\n\n> **Launch flags are yours on this tier.** On cold launch the backend supplies\n> `--disable-blink-features=AutomationControlled` for you. Attach connects to a\n> Chrome that is *already running*, so nothing vibatchium does can add a launch\n> flag after the fact — if you started Chrome without it, that tell is present\n> for the whole session. Include it in the command above.\n\n> **`--remote-debugging-port` is an open door.** It grants full browser control\n> to any process on the machine, and a page you visit can probe localhost to\n> discover it. Use it on a machine you trust, and close Chrome when you're done.\n\n## Security model\n\nvibatchium is built to drive *real* logins from an untrusted agent loop, so the\nthreat model is \"a credential must never reach the model, a screenshot, or a log\":\n\n- **Encrypted vault.** Passwords and TOTP secrets live in an XSalsa20-Poly1305\n  vault keyed from the OS keyring or `VIBATCHIUM_SECRETS_KEY`. A resolved secret\n  never appears in logs, HAR captures, the observe cache, or any agent-visible\n  response field (grep-tested in CI).\n- **Secrets are never rendered in the clear.** `fill --use-secret` masks the field\n  *in the page* (`-webkit-text-security`), applied before the value is written, so\n  every path that turns the viewport into bytes — the `screenshot` verb, the 5 fps\n  live-view stream, and VLM `vision_*` calls that ship the frame to a model —\n  captures dots, not the value. The mask **fails closed** (no write if it can't be\n  confirmed), covers password fields so a show-password toggle can't unmask, and\n  the accessibility snapshot returned by `map` / `diff_map` strips masked values so\n  the secret can't leak into the model's context as text either.\n- **Live-view is authenticated.** The WebSocket requires a per-server token and\n  rejects foreign-`Origin` connections (the CSWSH class), and *driving* the page is\n  a separate token from watch-only — a read-only link can be shared without handing\n  over the keyboard. Binds `127.0.0.1` by default (`--insecure-public` to override).\n- **Scraped content is marked untrusted.** MCP verbs that return page-derived text\n  carry `openWorldHint`, so a host can taint the output against prompt injection\n  instead of treating a scraped page as instructions; pure probes are `readOnlyHint`\n  and mutating verbs (`stop`, `secret_delete`, `storage_restore`) are\n  `destructiveHint`.\n- **REST shim.** Without `--caps`, the bearer token grants every verb including\n  `eval`, `secret_*`, and file-writing verbs — local-code-equivalent, so always\n  pass `--caps=...` in hosted mode. All vibatchium-written files are `0600`;\n  directories `0700`.\n\n## Honest limits\n\n- **5+ concurrent sessions = 1-2GB RAM.** Each persistent-context Chrome is ~200-400MB. Bump cap with `VIBATCHIUM_MAX_SESSIONS=8`.\n- **Vision spend cap is process-wide.** N fan-out agents share one daily/lifetime budget.\n- **Init scripts don't work on patchright backend.** `chrome.runtime` stays `undefined` — accepted trade for stealth wins.\n- **Login walls (X, LinkedIn) require attach mode.** Cold-launch fan-out can't defeat sites requiring authenticated sessions.\n- **Synthetic input has a CDP coordinate signature.** Every `click`/`type`/`hover`/`scroll` rides Playwright over CDP `Input.dispatchMouseEvent`/`dispatchKeyEvent` (`pageX==screenX`, no `CoalescedEvents`). Patchright patches the JS-context leaks, not the Input domain, and `humanize on` improves trajectory/timing realism but does **not** change the per-event signature. Behavioral walls that fingerprint it (DataDome/Kasada/HUMAN) want **attach-mode against a real headful Chrome you drive** — OS-level synthetic input (CDP-Patches) is headful + active-tab only and doesn't fit a headless, N-parallel daemon.\n- **`fetch` is a static-fingerprint lane, not a browser.** The curl_cffi `fetch` verb matches Chrome's JA3/HTTP2 but runs no JavaScript — it clears TLS-fingerprint gates, not DataDome/Kasada/Turnstile JS challenges. Fall back to `go` for those.\n- **Single daemon = single point of failure.** No HA built in.\n- **Behavioural detection now targets the humanizer directly.** Cloudflare's 2026\n  bot-detection work names mathematically ideal Bézier cursor paths and superhuman\n  click precision as tells. `humanize` improves on nothing-at-all, but it is a\n  pointer-trajectory model, not a physiological one — and it is **off by default**,\n  which on a behaviourally-scored site is the louder of the two states.\n- **One burned profile can taint every account that shares it.** Vendors now link\n  device telemetry across sessions *and* accounts. Use one profile per account,\n  never share a profile between identities, and don't reuse a profile that has\n  already been challenged.\n\n- **The `fetch` and `search` lanes are outside prompt-injection scanning.** The\n  scanner covers page-content verbs (`text`, `html`, `extract`, `map`, …). SERP\n  titles and fetched bodies are third-party text going straight into an agent's\n  context and are *not* scanned today. Treat them as untrusted input.\n\n## Authorized use\n\nvibatchium is built to drive sessions **you own**, with **your** credentials, on\n**your** machine — your accounts, your employer's, or a client's with their\nwritten permission. It is a tool for automating access you already have.\n\nThat boundary is not a formality, though the law around it moved in 2026. A US\ndistrict court had granted a preliminary injunction against an AI agent that\naccessed password-protected pages *through the user's own logged-in account*,\nholding that the user's permission is not the platform's authorization. On\n4 August 2026 the Ninth Circuit **vacated** that injunction and remanded\n(*Amazon.com Services, LLC v. Perplexity AI, Inc.*, No. 26-1444, published),\nconcluding that the operator had not \"accessed\" the plaintiff's computers under\nthe CFAA at all — \"it was the user who accessed [them], with the help of\n[the] AI agent.\" The California CDAFA claim failed for the same reason.\n\nRead that narrowly. It decides **who** accessed a computer, not whether evading\na technical block is access \"without authorization\"; the panel never reached\ncircumvention. A vacated preliminary injunction on remand is not a merits\nruling, and it leaves contract, terms-of-service, trespass and copyright\ntheories entirely untouched. What it does support is the shape of the tool:\nthe browser runs on your machine, under your login, and the reasoning leaned on\nexactly that — no operator computer ever touched the other side's servers.\n\nScraping a site's public pages, evading a wall you have no account behind, or\nautomating an account whose terms forbid it remain decisions you are making, and\nthe consequences are yours.\n\nCheck the terms of the site you are automating. If you are acting for someone\nelse, get it in writing.\n\n## License\n\nApache-2.0 core. Every default-install extra is permissive too — the `fetch` lane's curl_cffi is **MIT**. The only copyleft option is the opt-in `nodriver` backend (AGPL-3.0) — consult licensing before integrating it commercially. Nothing GPL/AGPL ships in the base install or `[all]`.\n",
  "bytes": 29325,
  "sha": "dfec5a78a545ecab40ee38a9153873d4352c5be5759355eb1ed240f2be00beca",
  "repo_slug": "trueoriginlabs/vibatchium",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_trueoriginlabs_vibatchium_d80f69c5/readme"
}