Vadgr-computer-use

Latest version: v0.6.2

Safety actively analyzes 971914 Python packages for vulnerabilities to keep your Python projects secure.

Scan your dependencies

Page 1 of 3

0.6.2

Browser-eval fix for strict-CSP pages.

Fixed
- `browser_eval` no longer silently returns `null` on pages with a strict nonce-based
CSP (`script-src 'nonce-...'`, no `'unsafe-eval'`), and no longer swallows page
exceptions (28). It ran page-world `eval()` via `chrome.scripting.executeScript`,
which the page CSP blocks and whose thrown errors surface as `undefined`, so every
call returned `{value: null}` regardless of the expression, DOM writes never landed,
and even a `ReferenceError` came back as `null`. `eval` now routes through the
`chrome.debugger` `Runtime.evaluate` path (like `press` / `snapshot`), which is exempt
from page CSP and reports exceptions, so a page error is thrown with its real message
instead of a silent null. The MAIN-world injection stays as the fallback when the
debugger is unavailable. Additive and wire-compatible; no `PROTOCOL_VERSION` bump.

Notes
- Extension and package versions bump to 0.6.2 in lockstep; `PROTOCOL_VERSION` stays 1.

0.6.1

Browser round 3.1: multi-profile targeting. When the extension is installed in
more than one Chrome profile (personal, work, several Google accounts), cua now
knows which profile each connection is and the agent can choose one, instead of
binding to whichever connected first. No protocol version bump: the handshake
gains additive profile fields and the capability list grows one op.

Added
- `profiles(op, ...)` op-group (a new Tier 1 tool): `list` returns every
connected browser profile with recognition context (`profile_id`, `browser`,
`is_current`, `window_count`, `tab_count`, `sample_tab_titles`) so you can tell
them apart by what is open in each ("the one with work Gmail and Figma");
`use(profile_id)` pins which profile the browser / tabs / windows / DOM ops act
within.
- `use_target` gains an optional `profile_id` that selects the connected profile
and (optionally) a target within it in one call.
- The extension mints a stable per-profile id (a UUID in `chrome.storage.local`,
which is isolated per profile) once and reports it plus the recognition context
in the `hello` handshake. No new permission (storage was already granted).
- `CUA_BROWSER_PROFILE` env var pins a default profile when more than one is
connected: it matches a `profile_id` prefix or a `sample_tab_title` substring.
- `browser(op="status")` grows a `profiles` array listing every connected
profile, so the pre-flight shows the choices.

Changed
- The browser transport keeps every accepted connection concurrently, keyed by
`(browser, profile_id)`, with a `current` pointer selecting which one ops route
to. This replaces the single-listener bond (one connection owned the pipe).
Selection follows a ladder: an explicit `profiles(use)` / `use_target` choice,
then the `CUA_BROWSER_PROFILE` pin, then the sole connection if there is exactly
one.

Fixed
- Never silently wrong on multiple profiles: with more than one connected and none
selected, the next op raises a terminal `profile_ambiguous` error that lists the
choices, rather than guessing (the same doctrine as 0.6.0 `target_lost`). If an
explicitly-selected profile disconnects, the next op is loud too, instead of
silently falling through to another profile.
- Concurrent cua instances can coexist (26). The browser server now honors the
`VADGR_CUA_BROWSER_DISCOVERY` env when writing its discovery file, symmetric with
the native host that already reads it; previously the server always wrote the one
per-user path, so a second cua process clobbered the first and the extension bonded
only to whichever wrote last. Set the same value for a cua process and the Chrome
that hosts its extension to isolate that pair; on WSL, `VADGR_CUA_BROWSER_DISCOVERY_WINDOWS`
overrides the Windows-side copy. This unblocks running one cua per profile / per agent.
- `profiles(list)` reports live window/tab counts, not a stale snapshot. The recognition
context (`window_count` / `tab_count` / `sample_tab_titles`) was captured once in the
`hello` handshake, so it went stale as windows were opened or closed (a closed profile
still reported its old windows/tabs). `profiles(list)` now re-queries each connected
extension for a live context and refreshes the cache; an unreachable session keeps its
last-known value so the list never fails. Found and fixed in the 0.6.1 WSL e2e round.

Notes
- Back-compat: a connection whose `hello` carries no `profile_id` (an older
extension) is registered under a synthetic `default` profile, so single-profile
setups are unchanged and need no new step.
- Extension version and package version bump to 0.6.1 in lockstep; the
`PROTOCOL_VERSION` stays 1 (the hello profile fields and the `profiles` op are
additive).
- The multi-connection registry and the profile handshake are pure Python + a
pure extension handshake with no path boundary, so Linux / Windows / macOS / WSL
behave identically; WSL is the parity boundary that proves the multiplexed
connections round-trip over the bridge. Validated on the automated gate
(`pytest` / `vitest` / `npm run build` / `npm run typecheck`); the live
two-profile run is the hardware verification round. This entry is re-checked
against the final diff at release.

0.6.0

Browser round 3: window/tab management (the multi-context session model). The

0.5.0

Added
- Session-target model for the browser tier: the extension pins an explicit
`{browser, window_id, tab_id}` target resolved once and used by every op by id,
instead of resolving each op against the last-focused window. By default the
agent opens its own dedicated window in your real Chrome profile (real
cookies/logins), kept separate so it never fights your foreground tab. The
pinned target survives service-worker idle-termination (`chrome.storage.session`)
and follows tabs the agent itself spawns (OAuth popups, `target=_blank`).
- `use_target(mode="owned"|"attach", window_id=None, tab_id=None)` browser op —
explicitly pin the session target. Attach mode snapshots the tab you are
currently looking at once, then pins it by id.
- New browser ops on the `chrome.debugger` path: `hover` (with an optional
`reveals` check), `dialog` (one-shot arm for JS `alert`/`confirm`/`prompt`/
`beforeunload`), `upload` (file inputs via `DOM.setFileInputFiles`),
`element_state` (visible / receives_events / enabled / focused / editable /
checked / value / bbox), `focus`/`blur`, `clear`, `get_value`, and `snapshot`
(paginated accessibility tree that pierces shadow DOM and frames; supersedes
`accessibility_tree`, which stays for back-compat).
- `upload` translates each file path to the browser process's OS before the op
crosses the wire, so a WSL path (`/home/...` or `/mnt/c/...`) reaches Windows
Chrome as a path it can actually read. Native Chrome paths pass through
unchanged.

Changed
- `query` now caps the node count and per-node text and paginates (`limit` +
`cursor` -> `next_cursor`), so a large page degrades to pages instead of a
single oversized result.
- The `browser` tool docstring documents that `screenshot` is a pixel tool, not a
browser op; `browser(op="screenshot")` now returns that guidance instead of an
opaque error.
- The extension requires the `storage` permission (for `chrome.storage.session`).

Fixed
- The browser tier no longer acts on whatever window the user last focused. Every
op targets the pinned window/tab by id, so a focus change (or a popup stealing
focus) can no longer move the target mid-task. When the pinned tab/window is
closed the op fails with a terminal `target_lost` error and remediation; the
tier never silently retargets the user's active tab.
- WSL: the MCP server no longer hangs on `initialize`. The startup subprocess
probes (the `reg.exe` native-host registration and the `cmd.exe`/`powershell.exe`
interop probes) inherited the JSON-RPC stdio pipe on fd 0; they now run with a
null stdin, so `initialize` returns immediately instead of blocking. (18)
- WSL: the native messaging host now auto-registers against the Windows registry
on first run. Platform detection resolves WSL2 through `detect_platform()`
instead of `sys.platform` (which reports `linux` under WSL), so registration
targets Windows Chrome and the extension bonds with no manual step. (19)
- The owned automation window opens at a real, hit-testable size (`state:"normal"`,
1200x900, still unfocused) instead of minimized. On WSL driving Windows Chrome a
`focused:false` window could open minimized (about 0px viewport), which made the
actionability hit-test fail and forced `force` on every mutation. A null
`elementFromPoint` result (a throttled or occluded window that is not composited)
is also no longer treated as covered, so a CDP-driven owned window is never
falsely gated.
- Native replies are correlated by request id instead of arrival order, and
navigation/read ops are time-bounded. A stray frame (a reconnect `hello`, or a
late reply from a timed-out op) can no longer shift every following reply by one,
and a page that never reports load-complete can no longer hang the pipe.
- The browser session tears down on an op timeout so the extension can reconnect.
A socket read-timeout previously left the buffered reader unrecoverable and
wedged the session; cua now closes the connection on timeout, the native-host
relay hits EOF, and the extension reconnects with a fresh session.

Notes
- No `PROTOCOL_VERSION` bump — every new op is additive and gated on the
extension's `supported_ops`; an older extension returns a precise
`op_unsupported` for a 0.5.0 op.

0.4.1

Fixed
- Restore the desktop screenshot tier on GNOME 49/50 (Ubuntu 25.10/26.04): add an
XDG Desktop Portal screenshot backend as the portable Wayland capture path. It
is tried after the no-dialog CLI tools, so GNOME 46 / Ubuntu 24.04 keeps using
`gnome-screenshot` unchanged (no new consent dialog) while GNOME 49+ — where the
CLI tools no longer work — transparently falls through to the portal.

Added
- Provider/resolver backend abstraction (`SessionContext` + `CaptureProvider` /
`InputProvider` + `BackendResolver`) so adding a desktop is one provider, not a
factory edit. `vadgr-cua doctor` now reports the resolved capture/input backend
and candidate applicability under `platform_backends`.
- Pure-python uinput input fallback (no `evdev`, no C compiler) and an X11 XTEST
executor via `python-xlib` (no `xdotool`).
- `vadgr-cua install-deps`: distro-aware provisioning (apt/dnf/pacman/zypper) for
`wl-clipboard` and the `/dev/uinput` udev rule. Prints the plan; `--yes` runs the
whole plan under a single privilege prompt — `pkexec` (graphical polkit auth, no
terminal sudo) when a display is present, falling back to `sudo`. This is the
second of the two install commands: `pip install` then `vadgr-cua install-deps`.

Changed
- `evdev` moved to the optional `[linux-uinput]` extra; `python-xlib` added as a
Linux dependency. A plain `pip install` no longer needs a C compiler.

0.4.0

Added
- Browser tier (Tier 1): an MV3 browser extension bridged to cua over native
messaging. Acts DOM-first (content scripts + `chrome.tabs`/`chrome.cookies`)
and escalates to a `chrome.debugger` CDP path only when a DOM op cannot
complete. Drives the user's own logged-in browser by selector.
- `browser` MCP tool (Tier ONE, MEDIUM) op-routed via `OperationGroup`:
`navigate`/`back`/`forward`/`reload`, `wait_for`, `query`, `read_text`,
`get_attribute`, `click`, `type`/`fill`, `select`, `scroll`, `cookies`,
`press`, `accessibility_tree`, and the `status` pre-flight op.
- `browser_eval` MCP tool (Tier ONE, HIGH): arbitrary JS in the page, kept
separate so the common ops keep a lower risk ceiling.
- Actionability gate (Playwright-style): before a mutating op (`type`/`fill`/
`click`/`select`) the target is checked for visible / receives-events
(hit-test) / enabled; a non-actionable target raises `op_failed` instead of
silently acting on a hidden or wrong node. A `force` param bypasses the gate.
- Self-verifying ops: `type`/`fill` return `{value, ok}`, `select` returns
`{selected, value, ok}`, and a checkbox `click` returns `{checked}`, so the
agent confirms an action landed from structured read-back rather than a
screenshot; the tool descriptions instruct it to. contenteditable editors are
filled via `execCommand('insertText')`, the only path that drives rich-editor
state.
- Executor seam + escalation: a DOM executor and a `chrome.debugger` CDP
executor behind one interface; on a DOM `ok:false` the escalation policy
retries over CDP (trusted `Input` events, `Accessibility.getFullAXTree`).
- Availability & failure model: a typed `BrowserError` taxonomy (`not_set_up`,
`not_connected`, `op_unsupported`, `proto_mismatch`, `waking`, `op_failed`)
mapped to a `ToolError` carrying remediation + a guided pixel fallback;
`status` reports `{connected, browsers, setup, reason}`.
- `computer_use.browser`: the wire protocol (`PROTOCOL_VERSION=1`, the `hello`
handshake, `supported_ops`), `BrowserBridge` (`NativeMessagingBridge` +
`FakeBridge`, session registry, per-OS manifest probe), and the native-host
stdio framing.
- `computer_use.setup.extension_setup`: installs the `com.vadgr.cua.json`
native-host manifest to the per-OS paths with `allowed_origins` pinned to the
extension's stable dev ID. On WSL it also auto-places the Windows-side relay
executable under `%LOCALAPPDATA%\vadgr-cua\`, so no manual copy step is needed.
- `extension/`: the MV3 extension (manifest with a pinned `key` for a stable
unpacked ID, service worker, op router, content DOM ops, the ported native
value-setter fill, the actionability checks, contenteditable fill, the
executor/escalation seam and `chrome.debugger` CDP executor, Offscreen
keep-alive), with vitest + happy-dom unit tests.

Changed
- Tool catalog grows from 21 to 23 (adds the two Tier ONE browser tools).
`tier_breakdown` now reports `{"0": 8, "0.5": 0, "1": 2, "2": 13}`.

Notes
- cua and `extension/` are independent builds that share no imports — only the
versioned wire protocol (`protocol.py` / `protocol.ts`).
- Validated end-to-end on real logged-in sites via the agent-driven runbook in
`E2E/0.4.0/` (see its per-OS results table); the framing, routing, error
model, DOM ops, fill, and actionability checks are also unit-tested headlessly.

Page 1 of 3

© 2026 Safety CLI Cybersecurity Inc. All Rights Reserved.