How we reviewed this: we built it in Docker on Swift 6.1 and dumped a real request payload from its own builder. It is a macOS app, so three of its ten tests need a Foundation class Linux lacks and the app itself could not run — that is our environment, not a defect. We made no Jev calls.
What it does
Hold a hotkey, speak, and Apple’s local speech recogniser transcribes. The app walks the frontmost application’s accessibility tree into a numbered element list, and one request per cycle picks an operation and a target — up to fourteen cycles. No screenshots anywhere; we checked.
Its handling of Jev’s 255-option limit is the right one: when candidates exceed it, the code splits them into batches and converges recursively. macbrow, in the same batch, overflows instead.
Key handling is the best here. Both keys live in the macOS Keychain, and every HTTP error string is passed through a replacement that scrubs the key before display. Nothing is written to disk or logged.
What the screen sends
Secure text fields are excluded in three separate places, so passwords genuinely do not leave. The README says so and it is true.
Everything else does. A payload we dumped from the real builder contained the window title (Inbox (3) - tim.private@gmail.com - …), an address bar including its query string, a message body, and a one-time code that happened to be rendered as static text. Field values are truncated at 80 characters and static text at 200; neither is redacted.
The settings screen says “Commands, app controls and available folder names are sent to TypeSafe.” That is a narrower description than what the code sends, and narrower than the README’s own version.
There is also a second vendor. A planner path posts your spoken command and the running app list to OpenRouter. The README never mentions OpenRouter — we grepped it and the docs folder — while the settings screen has a field for its key.
The confirmation gate is eight words
There is no confirmation step and no allow-list. The only gate is a confidence threshold, and which threshold you get depends on a substring match:
let destructive = op.id == "QUIT_APP" || (["MENU","CLICK"].contains(op.id) && ["quit","close","delete","remove","trash","empty","discard","clear"].contains { … })
let gate = destructive ? 0.6 : 0.2
“Place order”, “Pay”, “Send”, “Confirm”, “Move to Bin” and anything in a non-English interface take the 0.2 path. Below the threshold it does not refuse — it asks which one you meant. And because the check is inside if let target, operations without a target never pass through it at all.
One more thing worth knowing before you paste a key in: the planner is read from a user-defaults flag that nothing in the repository, the README or the settings screen ever writes. Store an OpenRouter key as the settings page invites you to, and the planner still never runs.
Verdict
Real craft in the parts that usually get skipped — Keychain storage, scrubbed errors, batching around a hard API limit, no screenshots. The gap is between what the settings screen promises about your data and what the payload contains, and a destructive-action check that stops at eight English words.
One commit, no CI. For the version of this with a policy layer, see macbrow.
See how it compares with other tools in Best Jev tools, tested hands-on.
Review updated Sep 20, 2026. Numbers quoted from the project are its author's own; we don't publish our own measurements of Jev.