Releases: brnyxx/jev-ra
Release list
jev-ra 0.2.8
0.2.8 is 0.2.6 with the install fix below. The human-check handoff that 0.2.7 shipped (the
needs_human reason, resume, per-host navigation pacing and the refusal/error wall kinds) is held
back for a later release, so 0.2.8 behaves on a check page as 0.2.6 did.
Fixed
uvx jev-ra install claude(andnpx -y jev-ra install claude) registered thejev-rathat uvx
or npx had put on PATH for that one run, a copy in their cache, by name; Claude Code then found no
jev-rato start. An entry point in the uv or npx cache is now skipped, so the command registered
isuvx jev-ra mcp(ornpx -y jev-ra mcp), as AGENTS.md says, and an installed entry point is
registered by its full path so a later PATH does not matter. The server itself is unchanged;
anyone who installed with 0.2.x can run the install again, or check withclaude mcp list.
jev-ra 0.2.7
Added
- A human check (a CAPTCHA, Cloudflare's "Just a moment...", a press-and-hold) is handed to a
person. jev-ra backs off and asks for the page once more; if the check is still there, it brings
the Chrome window to the front, raises a desktop notification (JEV_RA_NOTIFY=0turns it off)
and waits up to 120 s (JEV_RA_HUMAN_WAIT_S) for the page to stop being a check. Then the same
run carries on. jev-ra never solves a check, never hides that it is automated and never borrows
cookies from another profile. - A run nobody cleared the check for stops with the new reason
needs_human:detailnames the
site and the check and carriesresume.browser_run(resume=...)orjev-ra run --resume ID
carries the run on from its last page once the person has cleared it. A headless or remote
Chrome has nobody to show the check to, so the run stops at once anddetail.next_stepsays what
to do instead. blocked_by_sitesays which kind of wall it was:detail.kindisrefusal(access denied, a
403 with no check, a geo block) orerror.- The navigations a run starts are paced per host, at least 1 s apart (
JEV_RA_PACE_S), and a host
that answered 429 or put up a check is given twice as long each time, up to 30 s. The machine
the run is on is never paced. - The corpus and the bench count a run that needed a person apart, never as a pass or a failure.
Changed
- A page showing a check is never sent to the decision provider, not even as a speculative
request made ahead of time. - AGENTS.md tells an agent how to hand a
needs_humancheck to its user and resume, and tells
Codex users to raisetool_timeout_sec, since Codex stops waiting for a tool after 60 s. - Measured against 0.2.6 on one machine, alternating main, branch, branch, main, 5 runs each: every
task 5/5 verified in every round, and the medians overlap (Wikipedia 3.2-3.7 s against 3.5-3.8 s,
Google Flights 11.1-15.2 s against 12.4-13.9 s). The handoff costs nothing on a page with no check
(docs/benchmarks/2026-09-23-v0.2.7).
Fixed
uvx jev-ra install claude(andnpx -y jev-ra install claude) registered thejev-rathat uvx
or npx had put on PATH for that one run, a copy in their cache, by name; Claude Code then found no
jev-rato start. An entry point in the uv or npx cache is now skipped, so the command registered
isuvx jev-ra mcp(ornpx -y jev-ra mcp), as AGENTS.md says, and an installed entry point is
registered by its full path so a later PATH does not matter. The server itself is unchanged;
anyone who installed with 0.2.x can run the install again, or check withclaude mcp list.
Site
- The race opens with a laser tracing jev-ra's card instead of a lightning strike; the measured
times and the 4x playback are unchanged.
jev-ra 0.2.6
Changed
- The next decision is asked from the first reading that shows a step's effect, while the page is
still proving it has stopped moving, and the first decision of a run is asked while the opened
page finishes loading. An early answer is used only when the settled page asks the same request,
character for character, so no decision changes; the proof and the load are still waited for.
Runs send a few more decision requests than before (the ones whose page moved on are discarded
and counted as speculations).
Measured against 0.2.5 on one machine, alternating: Wikipedia 4.1-4.2 s against 4.3-5.3 s,
Google Flights 9.4-10.2 s against 11.7-12.8 s, form fill 1.4-1.5 s against 1.7-1.8 s
(docs/BENCHMARKS.md, 0.2.6). - A settle that ends without proof hands over the reading it ended on instead of reading the page
again. jev-ra bench --jsonnames the decision route (route: provider, endpoint, model) and keeps
every decision's round trip per task (decision_ms: n, median, p90, min, max and each value).
RELEASING.md says to commit that payload for the release head and the previous tag. The first
saved set: 275 decisions on the TypeSafe direct route, median 269 ms, p90 320 ms.
Docs
- Every figure the README, the site and the notes quote was traced to a committed row: the hero
showed another project's ratios and now shows jev-ra's own (8.5x / 7.5x / 4.0x against
browser-use's recorded runs, 2026-09-18); the per-step bar reads 1.4 s from the measured values;
the 0.2.4 corpus file is the real three-run pass; comparisons across days or routes say so. - Every race on the landing page opens with a lightning strike on jev-ra's lane, and jev-ra's meter
is a laser that fires again for each run it finishes. The measured times and 4x playback are
unchanged. docs/plans/benchmark-vs-field.md: how jev-ra will be measured against browser-use and the
commercial browser agents.
jev-ra 0.2.5
Fixed
- A field that opens an editor of its own when pressed (Google Flights' origin and destination) is
typed into that editor. Focus that the press moved onto another text field is where the value goes;
focus that did not move still goes to the observed field, so a swallowed click never types into
whatever held focus before. Google Flights ended instuck_loop0/5 on both 0.2.3 and 0.2.4. - A link's click carries the address it leads to, so the late-route wait added in 0.2.3 actually runs:
a site that pushes the new address a moment after the click (NHK's section links) is read after the
route, not on the hover menu the pointer opened. - The recorded Flights spec reads Zurich the way Google spells it (Zürich).
Site
- The landing page opens on a race: the same job for both tools, played at 4x from the measured
medians, in four languages. Switching language keeps the race, and the scripts carry a version so a
cached copy is not reused. - The recorded demo breaks its lines at the width they render, so Japanese, Chinese and Korean stay
inside the terminal; its Google page, cursor labels and step log follow the page's language; the
calendar starts its weeks on Sunday and the date click lands on the 20th. - The page title, description, accessibility labels, copy buttons, units and the remaining labels are
translated in Korean, Japanese and Chinese. - The README shows the landing page's step and architecture figures, animated, and carries accuracy
on real sites, what a site's error page does and where the changelog is, in four languages.
jev-ra 0.2.4
Changed
- A site's error answer is no longer read as the page. The observation carries the document's
http_status; a 5xx, a 429 or a short page that says it is an error is waited out for two seconds
and reloaded once, and a site still answering with an error is reported asblocked_by_site
(detail.wall = "http <status>"), never as a plainblocked. - Corpus rows record
http_statusandsite_error, the summary shows asitecolumn, and
scripts/soak.pycounts site errors, so a failure on the site's bad minute is told apart from a
product failure. - The three httpbin form tasks also run against httpbingo.org, so the forms family does not depend
on one host. - The recorded Google Flights task asks for a departure a month ahead instead of a day that has
passed.
jev-ra 0.2.3
Changed
- A click on a link whose router pushes the address late is waited out by the address, and the
route counts as arrived only when the page's title, text or controls changed with it. - An
<a>withouthrefthat carries a role, a tabindex, a handler or a pointer cursor is offered
as a control; ordinary pages gain no controls from this. - A date picker is driven from its calendar cells: once a click opened a grid of dates, the cells
are offered first and the opener is not clicked again. - A corpus spec may write a date as
{today+N}, so a booking task never asks for a day the site's
picker no longer offers. docs/BENCHMARKS.mdrecords the corpus at this release on both trees, three runs each, and what
run-to-run noise on live sites looks like.
jev-ra 0.2.2
Added
scripts/check_no_invented_input.pyfails a corpus results file in which any typed string was
not one of the task's values;scripts/soak.pyruns one task many times on one session and
reports pass count, median and p95 seconds, decisions and the reasons seen;scripts/check_site.py
says whether a corpus site is reachable, walled, and how many controls it shows.
Changed
- Every row of
docs/QUALITY_BAR.mdnames the check that proves it; the Debt list is empty. - The corpus names the address gov.kr now serves (plus.gov.kr; still walled, 3/3), and
corpus/egress.mdrecords oliveyoung's bot check as the eighth wall. - Browser-backed test coverage is 95.6 % (925 tests); a target whose setup fails is closed whatever
listens on 9222.
jev-ra 0.2.1
Changed
- The release workflow publishes to PyPI with the maintainer's API token (
PYPI_API_TOKEN), and a
re-run of the job skips files that are already there. Trusted publishing failed every run with
invalid-publisher;docs/RELEASING.mdkeeps its values in case it is revisited. - The suggestion-list and proxy tests read what CI reads: the settled state with the prefetch off,
and a caller flag that the Linux sandbox flag cannot shadow. docs/DEFINITION_OF_DONE.mdsays where every gate stands on this release and what remains, in
the order it pays off.
jev-ra 0.2.0
Nine lanes landed on top of 0.1.3, measured on the eighty-task corpus and on the public
benchmarks. Numbers and raw runs are in docs/BENCHMARKS.md; what still stands between this
release and the product bar is in docs/DEFINITION_OF_DONE.md.
Added
jev-ra serveexposes the same fourteen tools over HTTP and SSE;jev-ra trace <run_id>renders
a run;jev-ra profileprints where a run's time went;jev-ra cleanstops what jev-ra started
and empties its profile.- Named profiles keep their cookies (
--profile), and a run id and a log level an operator can set
(JEV_RA_RUN_ID,JEV_RA_LOG_LEVEL). JEV_RA_LOCALEreaches the launched Chrome and an attached one;JEV_RA_PROXYputs the browser
behind an egress, andcorpus/egress.mdrecords what the seven walled sites answered through it.- Two escalation reasons:
provider_errorwhen the decision provider will not answer, and
blocked_by_sitewhen a site serves a wall instead of a page, at the first request as well. - A question-shaped goal ends with a one-line final answer.
- A container image (
Dockerfile), and CI jobs for the image, macOS, Windows and a cold start
against a real Chrome. bench/public/: an act/observe adapter any harness can drive, with Online-Mind2Web and
WebVoyager runners judged by the benchmarks' own harnesses;scripts/bu_corpus.pyruns
browser-use on the same corpus under the same verify specs.- Forty more corpus tasks, every verify spec reviewed against the goal it proves.
Changed
- The page is settled by mutation rather than by budget, the observation after an action rides the
action's own round trip, and the next decision is prefetched while the page settles. - The state names what the last step opened; a control that opened a panel is shown as expanded
with the panel first; a control whose suggestions are open is not offered again while they are
up; links off the current site are offered last unless the goal names a site. - A consent wall is accepted before anything else is tried; a hash route counts as a navigation;
a link that asks for a new tab is followed in the tab this run drives. - The MCP server runs one tool at a time on the shared session, caps tool arguments at the edge,
closes its browser on SIGTERM and on exit, and exits instead of hanging when terminated. - Only web schemes are opened;
file:needs an opt-in. - The sdist carries the package, not the brand assets (3.2 MB to 208 KB).
Fixed
- A dead session is dropped so the next open starts over; a remembered CDP url is probed before it
is trusted; a target is closed when its setup fails. - The post-input settle waits as long as any other evaluate, and stillness is measured on a timer
as well as on animation frames, so a background target on Linux is not read too early. - A page that mentions a captcha is not a page that serves one.
browser_searchlists each url once and leaves the session as it found it.- A direct press goes through the same focus check as a decided one; a ref names the observation
it came from;doctorreports Chrome before it asks for a key.
jev-ra 0.1.3
Every MCP tool now declares the four annotation hints (readOnlyHint, destructiveHint, idempotentHint, openWorldHint), which clients use to decide what to confirm with the user. No tool is destructive; observe, extract, screenshot and wait are read-only. docs/USAGE.md lists the hints per tool.
PyPI: https://pypi.org/project/jev-ra/0.1.3/ · npm: https://www.npmjs.com/package/jev-ra/v/0.1.3