Use when driving a web page in a browser — clicking, typing, navigating, logged-in or JS-rendered pages. Jev picks each step from the elements observed, under a host allowlist and a step budget.
日本語の概要は準備中です。原文の説明を表示しています。
Use when driving a desktop GUI through a computer-use driver — windows, menus, native apps, OS dialogs. You build a table of safe actions; Jev picks the next one in about 0.4 seconds.
インストールする前に、エージェントに与えられる指示の中身を確認できます。
You stay the planner and the hands. Jev is only the fast "which one next?" in the middle. It returns an id from a table you built, so it cannot invent coordinates, text, selectors or tool calls. The worst a wrong answer can do is pick another action you already judged safe.
Web pages belong to jev-browser-use. This skill is for desktop apps and OS surfaces, driven through whatever computer-use driver you have (CUA Driver over MCP, the platform's native computer-use tool, an accessibility bridge).
If Co-Agent is installed (its engine answers on http://127.0.0.1:8792), let it drive.
It already holds the Mac's Accessibility and Screen Recording permissions, runs this same
loop natively (fresh observation, Jev picks one id from a closed menu, one action, a new
observation to verify) and adds what hand-built loops kept getting wrong:
occluded), instead of clicking whatever app is really on top;needs_approval with a ticket at once for purchases, deleting, sending, legal
acceptance, sign-in and security settings; it never types credentials;blocked instead of hanging.Agents with MCP use its tools computer_status, computer_observe, computer_act and
computer_run. Agents that shell out use the bundled client:
python3 <this skill>/scripts/coagent_cu.py setup --name "Hermes" # once per machine user
python3 <this skill>/scripts/coagent_cu.py status
python3 <this skill>/scripts/coagent_cu.py run --app "System Settings" --open \
--goal "Open the Appearance settings pane" --expect-text Appearance
python3 <this skill>/scripts/coagent_cu.py run --app Safari \
--goal "Fill in the profile form and save it" \
--input "Full name=Ada Lovelace" --input "Email address=ada@example.com" --expect-text "Thanks Ada"
python3 <this skill>/scripts/coagent_cu.py click --app "Epic Games Launcher" --target Library --near "top bar"
Always give --expect-text (or --expect-title) so success is checked, not assumed. Put
text to enter in --input; it is typed only into a field whose label matches. Exit codes:
0 done, 3 needs approval (nothing happened: tell the person what it wants and stop; do
not look for another way to do it), 4 not verified / stalled / loop, 5 blocked (say what
blocks it: the lock screen, the prompt's text, the missing permission), 2 usage or
connection error. The same privacy boundary holds: Co-Agent sends Jev element ids, roles
and short labels, never screenshots, field values or secure fields.
Use the loop below yourself only when Co-Agent is not installed on the machine.
Observe with your driver. Prefer accessibility/semantic state over pixels. Every ref, capture id and coordinate is good for this observation only.
Build the candidate table locally. Each row is an opaque id plus one complete, prevalidated action. Always include:
reobserve: look again, change nothingabstain: stop and ask for helpPrivacy gate. Nothing sensitive goes to Jev: no credentials, tokens, cookies, password-field contents, payment data, customer data, screenshots, files or unbounded page text. If the screen holds such content, abstain or handle it without Jev.
Ask once:
jev choose < request.json # Hermes: the jev_choose_action tool, argument `request`
{"schema": "jev.action_choice_request_v1",
"goal": "Open Settings and select Appearance.",
"observation_id": "capture-0042",
"regions": [{"id": "r1", "role": "button", "label": "Appearance", "interactive": true}],
"history": [{"selected_id": "open-settings", "outcome": "settings window opened"}],
"candidates": [
{"id": "select-appearance", "description": "Click the Appearance row in the Settings sidebar."},
{"id": "reobserve", "description": "Take a fresh observation without changing anything."},
{"id": "abstain", "description": "Do not act; ask the person for help."}]}
Pass the JSON on stdin or from a temp file. Never interpolate it into a shell string.
Run exactly the one action behind selected_id. Confidence under the floor (0.65, measured — see scripts/calibrate_choose.py; a second "does any candidate match" question was measured against the same cases and reduced no wrong actions, so it is not asked — see evals/choose-match/), or any Jev failure, comes back as reobserve. Always send regions: they are Jev's evidence the element is really on screen, and the same request scored 0.60 without them and 1.00 with them. Never derive an action from anything but the id.
Observe again and verify the postcondition yourself. A chosen id, a delivered click or a screenshot is not proof. Check application state before the next step. Stop after a bounded number of steps.
The bundled runner compares fresh local Accessibility state after each mutation (window
title, controls, selection and field changes; ephemeral driver tokens are ignored). If
the same chosen mutation leaves that state unchanged twice, it stops as
stalled_action before asking Jev a third time. An unchanged screen is not proof that
the requested effect failed forever (some apps update asynchronously): report the
unverified result or make a new bounded attempt after the app settles, rather than
claiming success. Unknown choice ids stop as invalid_choice without dispatch.
Neither screen contents nor the local comparison fingerprint are sent to Jev.
This is a conceptual adaptation of the fresh-observation/unchanged-state loop in
Jev Voice / jev-cua at commit
098e9348fbfc7afae61575960c15cdaaae960b0b. The linked Swift repository has no
tracked license at that commit, so no code was copied. Its sped-up demo preview is
not evidence of runtime speed, and its no-confirmation queue does not supersede the
approval rules below. Our runner retains cua-driver, closed candidate ids, and
independent goal verification. The bundled AX runner does not issue raw coordinate input;
a grounded manual Jev + Cua Driver pixel loop remains available for AX-invisible content.
Neither path uses AppleScript input.
Driving a GUI gives you no new permissions. Sending, publishing, paying, purchasing, deleting, changing credentials or security settings, and anything touching customer data still need the person's explicit yes, exactly as they would without a GUI. Use your driver's standard permission mode; never an approval-bypass flag. The person does all sign-ins, 2FA and payment prompts themselves.
If the driver, the key or the target is unavailable: stop and say what is missing. Do not improvise another way to control the screen.
jev choose --mock answers reobserve with no network call, for testing your loop.
The loop above is the contract. scripts/jev_gui_agent.py is a working implementation of it —
the desktop counterpart to jev-browser-use's runner — so you do not have to rebuild the
observe/choose/act cycle by hand:
python3 <this skill>/scripts/jev_gui_agent.py \
--pid 26955 --window-id 46041 \
--goal 'Open the Library page in YouTube Music' \
--expect 'Library' --max-steps 12 --json
It drives cua-driver over MCP, builds the candidate table from the accessibility tree, sends
jev.action_choice_request_v1, and performs only the action behind the returned id. The runner
uses jevkit's provider selection and credential lookup (TypeSafe, then OpenRouter, then
Venice); it never copies a fallback provider's credential into TYPESAFE_API_KEY. Exit 0
verified, 4 unverified, 2 refused to start, 6 abstained. --max-regions defaults to 26 so the
table stays inside the 32-candidate contract once reobserve and abstain are added.
If the driver binary is missing or does not speak MCP, the runner prints one FAIL: line and
exits 2. Set CUA_DRIVER_BIN or install the driver; do not retry the same command.
If the AX snapshot contains only window chrome and the macOS menu bar (as Epic Games
Launcher can), the runner now stops with no interactive elements observed rather than
asking Jev to click a global menu item. This is a safe stop, not proof that the app
has no visible controls. A grounded manual Jev + Cua Driver pixel loop may be used for
custom-drawn content: derive coordinates from the current screenshot's actual pixel
geometry, not screenshot_scale; choose only safe actions, then independently read
back the page. Cua Driver's effect: unverifiable means it posted input, not that the
app responded. If grounded clicks still do not change the page, stop rather than
retrying an inert action or claiming a driver fix.
For an opt-in end-to-end local smoke on macOS, run
python3 scripts/smoke_gui_fixture.py from the source checkout. It compiles a disposable
AppKit window, discovers its exact Cua window id, and runs the bundled Jev chooser +
Cua AX runner twice against a changing window title. It requires the real driver and
Jev credential, checks one activation and a verified title transition per run, and
terminates the fixture even on failure. It does not validate custom-drawn Epic UI
or pixel delivery. Do not treat a passing fixture as Epic navigation proof.
If you cannot run it, fall back to the loop above by hand — but do not fall back to
AppleScript UI scripting, xdotool or another GUI driver. Stop and say what is missing.
--plan: a multi-step command in one runpython3 <this skill>/scripts/jev_gui_agent.py --plan \
--goal 'Open System Settings, go to General and then open About' \
--expect 'About' --json
Use it when the person gave a spoken-style command with several steps, above all one that
starts by opening an app or a site. Without it you run the loop once per hop and spend a full
turn of your own composing each command: measured, the loop took 8 seconds and the agent around
it took 36. With --plan the same command is one run: about 1 second to plan, then each step.
Do not use it for a single navigation goal such as "open the Library page". The plain loop
is already one step there, and a plan adds a model call and sends the command to one more
service for nothing. Do not use it either when each hop needs its own --expect: a plan is
verified once, at the end.
What it does:
JEV_PLAN_MODEL, else
TEXT_MODEL, at TEXT_MODEL_BASE_URL; key from TEXT_MODEL_API_KEY or
OPENROUTER_API_KEY, else the OS secret store) turns the command into ordered steps from a
closed vocabulary.open_app (open -a <name>, a name and never
a path), open_url (http and https only), press_key, menu, scroll, wait.click and type_text go through the same Jev loop, one action each. Dictated text is typed
as given, into a field Jev picked, never at wherever the focus happens to be. After the
action, the runner reads the window again (and once more after a short settle if unchanged).
A driver's delivery acknowledgement alone is not a completed step: an unchanged AX state
ends the plan as action_unverified, without running dependent steps. An AX change is
evidence of progress, not proof that every semantic intent succeeded; verify the
expected final state independently, and use per-hop checks for consequential actions.--pid and --window-id become optional: after open_app or open_url the runner aims at the
window that opened, and with neither it starts from the front window. --max-steps stays the
ceiling on Jev calls for the whole command, not per step.
It fails open. No key, a timeout, a reply that is not a valid plan: the goal runs as one loop,
exactly as without the flag, and the result says "plan": {"status": "fallback", "reason": ...}
so an outage is never mistaken for a plan. A step that fails ends the plan, because the steps
after it assumed it happened; the run then reports unverified (exit 4). Rerun without --plan
or take that hop by hand.
The --json result gains a plan object: status, reason, latency_ms, model, cache,
dropped, and steps, each with kind, target, mode (direct, jev, ignored for a kind
outside the vocabulary, not_run after a failure), ok, duration_ms and detail.
A repeated command need not be planned twice, and plan.cache says what the plan cache did.
JEV_MEMO=shadow, the default, still asks the model every time and only records shadow_agree
or shadow_differ against the stored plan. JEV_MEMO=on reuses the stored plan (hit) and
skips the 1 second call; off stores nothing. Only the planning call is ever skipped: every
step is still observed, chosen, executed and verified, and a stored plan goes through the same
validation and never-send filter on every read. A command that looks sensitive is never
stored, entries last 7 days, and a run that fails a step or ends unverified forgets its plan,
so a plan is reused only after a run that passed its --expect. Stored steps include dictated
text, in a private file on this machine; JEV_MEMO=off keeps nothing. The mode is the person's
setting, not yours to change mid-task. Details: docs/response-caches.md.
Three rules that are yours to keep:
--goal. Put anything to be typed in quotes or after type:; quoted and dictated text is
treated as content, never as a request.plan.dropped. One the person did ask for is kept and marked risky. This is a
backstop behind the Authority rules above, not a replacement: get the person's yes before you
pass a command that asks for any of those.The two-model split (a fast text model plans, Jev grounds every on-screen target) follows savka777/jev-use, MIT.
jevkit.local_goal builds whole prevalidated action ids for a caller-owned local loop; it does not launch apps or replace the normal Co-Agent path. See the local goal contract for the API, measured synthetic-browser results and remaining gates. Use only on explicitly authorized non-sensitive screens with exact target scope, freshness checks, action/deadline budgets and independent actual-effect verification. Its candidate descriptions include supplied non-sensitive bound text values, unlike this skill's label-only desktop path; sensitive/contact-shaped inputs and unknown/protected bound-field types are refused. No confidence floor is lowered, and neither a model DONE choice nor visible done text alone proves the requested outcome. Native and end-to-end qualification are separate from warm headless-engine timing.
This skill is the loop. Machine-specific runtime — which driver binary to start, how it is
registered as an MCP server, where the credential comes from, which machine map to resolve
paths against, and which older skills are retired — belongs to the fleet, not to this public
repo. On a managed fleet, read the fleet's shared/rules/jev-computer-use-fleet.md (Hermes:
~/.hermes/shared/rules/) before the first GUI action, and resolve $HOME-relative paths
against that fleet's machine map.
An earlier preview of this loop used hermes.cua_jev_choice_request_v1: capture_id, pixel
bounds and a per-region confidence, pinned to model jev-1.13.0. It is withdrawn and
incompatible with the request above. Regions here carry id, role, label, interactive
and no coordinates; the model is jev-latest. A script or skill that still sends the old
shape must be updated, not renamed. If something hands you the old schema, stop and report it.
まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Use when driving a web page in a browser — clicking, typing, navigating, logged-in or JS-rendered pages. Jev picks each step from the elements observed, under a host allowlist and a step budget.
日本語の概要は準備中です。原文の説明を表示しています。
Use when a transcript has to be cut to a fixed size and you must choose which turns go. Jev marks each turn keep, summarize or drop. Measured: it does not make a handoff better.
日本語の概要は準備中です。原文の説明を表示しています。
Use when a task is already judged hard — pick which paid frontier seat takes it, then keep Jev watching the delegated run so it interrupts you only when the run needs a decision.
日本語の概要は準備中です。原文の説明を表示しています。
Use on a mailbox export to sort mail into needs reply, updates, promotional, sales and spam — which messages are addressed to the person at all. For a support queue use jev triage.
日本語の概要は準備中です。原文の説明を表示しています。
Use on passages a search just returned (memory, vault, session history, wiki, web) before reading them in. Jev ranks them, drops the irrelevant, and flags prompt injection hidden in the text.
日本語の概要は準備中です。原文の説明を表示しています。
Use to pick the cheapest good-enough model or effort for a turn or a delegated task (lanes small to escalate), to decide continue/retry/verify/escalate/complete after each cycle, or to tune routing.
日本語の概要は準備中です。原文の説明を表示しています。