neuron-explorer
Qwen3.5‑4B 전용 조향형 뉴런 탐색기, 모든 MLP 뉴런을 밀어 결과를 보관·탐색
Jevitate는 실제 브라우저에서 웹앱을 탐색해 증명 가능한 내용만 보고, 결과를 결정적 재생으로 전환해 수정 검증·CI 게이트를 지원합니다
Jevitate explores your web app in a real browser, reports only what the browser can prove, and turns every finding into a deterministic replay: verify the fix, commit the regression, gate CI. Open sou
개발 도구TypeScript · JavaScriptGitHub @matt-cochran온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
Autonomous browser testing that turns discovered bugs into deterministic regression tests. A model may choose what to try; only browser evidence decides pass or fail. CLI + MCP server.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Autonomous browser testing that turns discovered bugs into deterministic regression tests.
Website · Docs · Demo · Changelog
Jevitate explores your web app in a real browser, tries to break it, and reports only what the browser can prove: HTTP 5xx responses, uncaught exceptions, hangs, failed success checks, broken rules you declare. Each defect comes with a Recording that reproduces it. Jevitate replays it to confirm a fix and commits it as a regression you can run in CI.
Nondeterministic discovery. Deterministic verification. A model may suggest what to try next. It never decides whether your software passed.
Demo: a 2-minute, no-API-key walkthrough is in docs/demo.md. A form says "Saved" while the server returns HTTP 500. Jevitate finds it, reproduces it 3/3, commits it as a regression, and verifies the fix.
Traditional E2E: you write a test ──► it runs ──► it catches the failures you anticipated
Jevitate: explore ──► detect (evidence) ──► reproduce ──► commit a regression ──► verify the fix
(goal, adversarial, (code-decided (replay in (regression capture) (verify-fix,
coverage, feature) oracles) fresh contexts) regression run)
Jevitate doesn't replace the E2E tests you write. It finds the failures nobody wrote a test for, and hands each one back as a deterministic artifact.
Needs Node.js 22+ and an app running locally (examples use http://localhost:3000).
1. Install
npm install -g @jevitate/cli
jevitate install-browser # the pinned browser Jevitate drives (shared, never removes other revisions)
2. Set up the repo. Run this from your app's repository:
jevitate init
It creates .jevitate/ (Journeys, regressions, baselines, logs, and an example
environments.json), installs agent skills for Claude Code, Codex, Cursor
and AGENTS.md, registers the MCP server, and asks for any missing keys (OPENROUTER_API_KEY for
text generation, and also for Jev's judgment unless TYPESAFE_API_KEY is set; see
docs/authentication.md). Keys are optional for step 3. Without a
terminal (CI, a coding agent), init never prompts: it reports which keys are missing, and you
add them later with jevitate ai setup <generation|judgment>. It ends with a short next steps
list that fits what it set up.
Key entry is masked (each character shows as •; the instructions stay on screen). init and
jevitate ai status name each key, its provider and where it comes from (from env OPENROUTER_API_KEY or from ~/.jevitate/credentials.json), and check it with the provider (a
live, non-billable auth call: valid, INVALID (HTTP 401), or could not verify). A key the
provider rejects is never stored. To rotate or replace a stored key, run jevitate ai setup <feature> --replace (or jevitate init --replace-keys for all of them). Offline or in CI, pass
--no-verify. See authentication.
3. First run: try to break a form. No keys needed, because the adversarial mission plans its misuse in code:
jevitate explore --strategy adversarial --url http://localhost:3000/settings --fake-ai
It double-submits, feeds empty, boundary, long, unicode and invalid values, cancels and reloads
mid-edit, and acts while a save is still pending. It prints the outcome (clean,
defects-found, inconclusive, …), each defect with its fingerprint, the result file and a
next: step. The full result (evidence, the Recording, a ready-to-file issue draft) goes under
.jevitate/logs/<date>/ (where jevitate keeps things).
--json prints it as a JSON envelope instead. The exit code is the outcome
(table below).
--url's origin. Add --allow <origin> for each origin the app needs,
and include the app's own origin too, since --allow replaces the default.--fake-ai swaps the mission's advisory model calls for deterministic stand-ins. Nothing it
reports depends on them.--storage-state auth.json (authentication).--extension <dir>
(browser extensions).With keys, a goal-directed run reaches an end state, and code checks it:
jevitate explore --url http://localhost:3000/profile --goal "set the last name to Litmus and save" \
--success 'requestMade:PUT /api/profile' --success 'reloadThen:valueEquals:[data-testid=last-name]|Litmus' \
--real
It succeeds only if the save request was sent and the value survived a reload. The model saying "done" doesn't count.
4. Next steps
| To | Run | Docs |
|---|---|---|
| keep a flow as a replayable Journey | jevitate explore-author-journey --url <url> --goal "…" --success "…" --id checkout --name Checkout --real, then jevitate journey promote checkout | journeys |
| record a flow by clicking through it | jevitate record --url <url> | journeys |
| replay it anywhere | jevitate journey run checkout --env staging | environments |
| make a narrated demo | jevitate demo "Save your display name" --env local --success "…" --real | demos |
| prove a fix, with evidence | jevitate verify-fix --result <run>.result.json --fingerprint <fp> --record-video | verification |
| gate CI | jevitate check --suite jevitate-suite.json (JUnit + SARIF; exit 1 = a gating finding) | ci |
| let your coding agent drive | ask it in plain words. The skills and MCP tools init installed do the rest | agents |
The demo runs against the repo's example app. It needs no keys and all of its output is real:
jevitate explore --strategy adversarial --url http://127.0.0.1:5190/demo/profile \
--invariants apps/example-site/demo-invariants.json --fake-ai --out demo-runs
# outcome: defects-found. "HTTP 500 from /demo/api/profile", and the invariant
# "saved-means-stored" (the page said Saved, but the server kept the old name)
jevitate verify-fix --result "$RESULT" --fingerprint "$FP_500"
# verdict: still-reproduces. "the defect's fingerprint fired on all 3/3 replay(s) that ran"
jevitate regression capture --from "$RECORDING" --result "$RESULT" --fingerprint "$FP_INV" \
--id saved-means-stored --dir demo-regressions
jevitate regression run saved-means-stored --dir demo-regressions # reproduces (exit 1)
# ...fix the bug, restart the app...
jevitate regression run saved-means-stored --dir demo-regressions # fixed (exit 0)
Every run is headless by default, CI included. To show an audience what jevitate does, open a visible browser and slow it down, or record it:
# A visible Chromium, each browser operation slowed by 250 ms (override with --slow-mo <ms>):
jevitate explore --strategy adversarial --url http://127.0.0.1:5190/demo/profile --fake-ai --headed
# Headless, recorded: the videos are listed in the result (videoPaths) and the summary (VIDEO)
jevitate explore --strategy adversarial --url http://127.0.0.1:5190/demo/profile --fake-ai --record-video
--headed (or JEVITATE_HEADED=1), --slow-mo <ms> and --record-video [dir] work on every
explore strategy, journey run and verify-fix; regression capture|run take --headed and
--slow-mo. A headed explore run also shows an on-page overlay (hide it with --no-overlay).
--headed needs a display: without one (no DISPLAY/WAYLAND_DISPLAY on Linux; WSL2 needs WSLg)
it is refused (exit 64) — use --record-video instead. See
operations: demo mode.
Evidence for a defect, and screenshots of any run:
# Per defect: its minimal repro replayed with captions, the failing step marked with the actual
# signal ("Save → server returned 500 (PUT /api/profile)"), a clip + before/at screenshots
# (defects[].evidence; linked from the issue draft, report, JUnit and SARIF)
jevitate explore --url http://127.0.0.1:5190/demo/profile --goal "save the profile" --fake-ai --evidence-video
# One masked screenshot per distinct screen (or `--screenshots steps`: one per step) + index.md
jevitate journey run my-journey --screenshots
--screenshots [screens|steps|<dir>] works on every explore strategy, journey run|annotate|demo
and verify-fix; verify-fix --record-video gives a before/after clip pair. Registered secrets are
masked in the pixels of every clip and screenshot (a capture whose mask cannot be proven is skipped,
never written). See operations: evidence and screenshots.
A Journey is a replayable, typed flow you author from a goal, record by demonstration, or get
from explore. It runs the same on every machine, self-heals under policy and loads as a test in
CI (Journeys).
# Intent: why, not only what. Drafts goals, success criteria and per-step objectives on playback;
# nothing is written until you review and approve.
jevitate journey annotate checkout --real
jevitate journey annotate checkout --approve
# Environments: a Journey knows no host. Name yours in .jevitate/environments.json (committed, no
# secrets), then pick one per run. A step on any other origin is refused before a browser opens.
jevitate journey run checkout --env staging
jevitate regression run saved-means-stored --base-url http://localhost:3000
# A narrated demo of a Journey: video + .vtt subtitles + a Markdown guide with screenshots
jevitate journey demo checkout --env staging --video demos/checkout.webm --guide demos/checkout.md
# Or from a one-line request: explore -> minimize -> author -> annotate -> DRAFT demo
jevitate demo "check out with a saved card" --env staging --success 'urlIncludes:/order/confirmed' --real
jevitate demo approve <id> # the one human approval: renders the final demo, promotes the Journey
Existing Journeys keep working unchanged: intent fields and environments are optional.
--env/--base-url work on journey run|annotate, regression run and load run. Sessions and
secret fields per environment live in ~/.jevitate/targets.json, never in the repo. demo refuses
an environment flagged production: true. Details: Journeys,
environments, demos.
Jevitate is the MIT-licensed, open-source journey foundation for Journeeze. Jevitate verifies that a flow works in a real browser and produces replayable journeys, demos and step-by-step guides. Journeeze brings those journeys into the live product as help and gathers what only people can tell you: what made sense, what confused them and where they got stuck.
Journeeze imports your .jevitate/ personas, jobs and journeys. Your team reviews and publishes
guides, then adds the Journeeze SDK to the app.
People can follow guides or opt into element-anchored comments and reactions; your team can
triage related reports into clusters and file them as GitHub issues.
Jevitate works independently of Journeeze. Journeeze is a separate hosted service in early access, with its own account, site key and service terms. See journeeze.dev for product details and early access. Jevitate may make a local, terminal-only suggestion when a project's local evidence indicates shared testing needs; it never connects or sends anything. A person can dismiss that exact suggestion or opt out locally; see Journeeze local team-need hint.
Hand-written E2E tests check the paths someone thought of. The bugs that reach users tend to sit somewhere else: a double submit, a name with an emoji, a reload halfway through an edit, a request that hangs, a page that says "Saved" when the server said 500.
Autonomous agents can find those paths, but "the AI said it looks broken" is not a test result, and an agent that clicked around once is not a regression suite. Jevitate keeps the exploration and replaces the judgment with evidence:
verify-fix replays 3 times by default. An intermittent
signal is reported as intermittent, never as fixed.inconclusive, never clean.| Decided by | |
|---|---|
| What to try next | Goal and usability missions: Jev (TypeSafe's judgment model) picks among the controls code found. Adversarial, coverage, exploratory and --feature missions: code strategies, with Jev's opinion recorded as advisory only. |
| Whether it failed | Code only: HTTP 5xx, uncaught exceptions, console errors, failed requests, hangs confirmed by replay, your --success checks, your invariants, your backend log matchers. |
| Whether it's fixed | Replay: the finding's Recording, in fresh browser contexts, compared by fingerprint. |
| What gets committed | A Recording (typed, deterministic steps) plus its oracle, minimized where possible. |
More: how it works, including the architecture and package map.
| Missions | explore with a --goal, or --strategy adversarial | coverage | exploratory | usability, or --feature <name> (exploration) |
| Success checks | URL, visibility, text, values, counts, network (requestMade, responseStatus), persistence (reloadThen), an http: end-state read of an allow-listed origin (a dev mail outbox), computed style and layout. Find-out goals are answered only with grounded claims (success checks) |
| App-declared invariants | rules over DOM, network and read-only probes, checked around every action (invariants) |
| Reproduce and verify | verify-fix, regression capture, regression run, and ledger add / ledger verify to re-check a finding by fingerprint long after its run (verification) |
| CI | jevitate check --suite with a budget, JUnit and SARIF; report and diff for deduped findings and baselines (CI) |
| Real apps | storage-state logins, bound secrets and TOTP, fixtures that reset state around every replay, repeat-and-vote, persona and multi-actor runs (auth, fixtures, ) |
Jevitate gives Claude Code, Codex, Cursor or any MCP client a bounded QA loop: run a mission, read a typed result, re-check a finding after a fix.
jevitate init # installs skills for detected agents and registers the MCP server
jevitate mcp --print-config claude # or cursor | codex | json: print the snippet, write nothing
Run non-interactively like this, init never prompts for keys — it reports what's still missing
(keys: generation not configured — set OPENROUTER_API_KEY (OpenRouter) or run \jevitate ai setup generation`) and exits 0 regardless, since the rest of init (skills, MCP registration) still succeeded. Set the keys separately with jevitate ai setup <generation|judgment>`.
The MCP server exposes an allowlist of domain tools (run_journey, queue_exploration,
get_mission_result, verify_fix, annotate_journey, create_demo, run_check, …). MCP is a
convenience for agents that could run the CLI anyway, so every CLI command is reachable over MCP and
every MCP tool from the CLI; the tools that mirror a command run it in process with typed, closed
arguments and confined paths. Only mcp, ui, init, ai setup, record and trusting a source
stay off MCP, each for a stated reason. Raw browser tools such as browser_click or page_evaluate
are forbidden: an agent asks for a mission or a Journey, it never drives the page. Approving or
cancelling an inbox item stays human-only, in jevitate ui. See agents and MCP.
Everything an agent can do over MCP you can do from the shell, over the same stores
(~/.jevitate/missions/, ~/.jevitate/inbox):
jevitate mission queue spa --strategy coverage --route '/settings/**' # enqueue against a promoted target
jevitate mission run # drain the queue
jevitate mission result <id> # status + typed result; exits with its contract code
jevitate inbox list # also: show, command, queue-retrieval, queue-action, health
inbox command <id> is burn-after-read like MCP's get_command: unread human input needs
--reveal, which consumes and prints it. Approving or cancelling an inbox item stays human-only
(jevitate ui). Flags: docs/cli.md.
--allow-destructive. Find-out goals are read-only unless you pass
--allow-writes, and hang replays never re-send a paid write. Every write request a run
fires is listed.Details: safety model · SECURITY.md.
A run never answers with a crash. Every run ends in a typed outcome, and its transcript and Recording are flushed step by step.
| Outcome | Exit | Meaning |
|---|---|---|
clean | 0 | finished its budget and found nothing (goal: the success checks held) |
defects-found | 1 | at least one confirmed defect (goal: a success check did not hold) |
inconclusive / crashed | 2 | the run itself could not do its work, so its silence proves nothing |
hang | 3 | the app hung, and the hang reproduced on replay |
intermittent | 4 | a hang was observed but did not reproduce on every replay |
A usage or input error (a bad flag, an unreadable suite, an unknown id) exits 64, never 1.
Goal runs also report their own outcome (succeeded, failed, exhausted, blocked, …). Every value, and
the exit codes for every command, is in
docs/outcomes.md. Without --json, commands print a human summary; with
--json, the JSON envelope.
--secret only redacts a value. To start logged in, pass a Playwright storageState
(--storage-state auth.json). To drive a login form, bind a field to an environment variable
(--secret-field 'label=Password=env:APP_PASSWORD', plus --totp for MFA): code types it, and the
model only sees «secret:VAR». Details: docs/authentication.md.
Jevitate is pre-1.0 and under active development. Known limitations worth knowing:
--real), and they cost money per model call. Runs
report usage with the full cost of Jev and generation calls; a model with no known price
makes the total partial until you configure one
(operations).verify-fix, not committed by
regression capture. Declare the broken rule as an invariant to commit it
(verification).jevitate ux, explore --strategy usability) are a PREVIEW and advisory.
Each finding is a claim verified by code, but Jev's categorization and the two-question grade
are tuned on fixtures only, not yet calibrated with the real model across apps
(UX findings, #198).Bug reports, feature ideas and pull requests are welcome. Start with CONTRIBUTING.md. It covers the local setup, how to run a single test file, and the few invariants every change must keep. Please report security issues privately (SECURITY.md).
pnpm install && pnpm -r build
pnpm exec vitest run packages/explore/src/success-checks.test.ts # one test file
pnpm lint
| Evidence | hangs (confirmed by replay), page timing, backend log correlation, redacted issue drafts (exploration, operations) |
| Journeys | author a replayable flow from a goal, replay, self-heal under policy, load-test, share (Journeys) |
| Demos | journey demo renders a Journey as a narrated video, .vtt subtitles and a step-by-step guide; demo "<aspect>" --env <name> --success <check> explores, minimizes, annotates and drafts one from a one-line request, and demo approve <id> promotes it (demos) |
| Usability review | ranked, cited findings: claims verified by code (a probe, the product facts, observed friction). Advisory, never a gate (UX findings) |