jevgrep
★ 866dzhng/jevgrep
Finds code by what it does rather than what it matches: a CLI for coding agents that asks which files and which regions are relevant to a description.
Grades prose against twenty-one named writing tics, asking every rule about every line, and writes its findings as a brief for a coding agent to act on.
View on GitHub →Hands-on review
Grades writing line by line against 21 rules. Every rule really is asked about every line, and a short answer set is now an error rather than a clean report.
Good for
Watch out for
Tested Sep 23, 2026 at db600093f3e8 · node:24 in Docker, its own suite, then the built CLI against a stand-in that logged and counted every question and could answer only some
How we reviewed this: we ran its suite, then drove the built CLI against a stand-in that logged every request, counted every question, and could be told to answer only some of them. We made no Jev calls.
A rule-based grader for prose, aimed at the tics that make text read as machine-written. You run it on a document and hand its output to a coding agent, which proposes replacements you then review. The shipped rule set is called no-ai-slop and its members are specific rather than vague: banned_word, binary_contrast, colon_reveal, faux_insight, em_dash_crutch, bold_lead_in_list, fake_profound_kicker.
Its first example line is a fair target:
# 🚀 The Ultimate Paradigm Shift in Modern Data Architecture
Runs every rule against every line in parallel. No skimming, no missed lines.
That is checkable, so we checked it. On the shipped example — 16 non-empty lines — the stand-in received:
requests: 21 (one per rule)
questions per request: 16 (one per line)
total questions: 336
Twenty-one rules by sixteen lines, exactly. No sampling, no “first N lines”, no asking the model to find the problems itself. The state is the whole document and each question names the line it is about:
“For the line L0001 answer: Does the line contain a word from this list: delve, foster, leverage, utilize, facilitate, …”
That is the right shape for this problem, and it is the thing most writing tools get wrong by asking one open question about a whole document.
A violation we planted on L0001 came back attached to that line, with the rule letter and the line text.
Nothing used to compare the answers that came back against the questions that went out. We pointed it at a provider that answered the first question of each request and dropped the other fifteen, and got a clean bill of health: No rules violated., exit 0, on a document with a violation we had planted. 336 questions asked, 21 answered, document reported clean. Reported with the suggestion that a missing answer id be treated as an error rather than as “rule not violated”.
Fixed in v0.2.6. Same stand-in, same document, at 2147e46:
| what the provider did | questions asked | answered | result |
|---|---|---|---|
| answered one of sixteen per request | 336 | 21 | Error: Provider (jev) returned incomplete answers: missing 15 of 16 answers, exit 1 |
returned an empty answers object |
336 | 0 | missing 16 of 16 answers, exit 1 |
| returned a non-JSON 200 | 336 | 0 | Error: Provider (jev) returned invalid response: received non-JSON response "<html>hi</html>", exit 1 |
| answered everything | 336 | 336 | No rules violated., exit 0 |
The non-JSON row was a second finding in the same report — it used to surface as Error: Cannot convert undefined or null to object, which failed safely but pointed at the wrong place. Now it names the provider and shows what it sent.
That matters more here than it would elsewhere, because “no missed lines” is this tool’s whole promise. A clean report from a truncated or rate-limited response used to look exactly like a clean report from a real one; now it cannot.
A second run over the same document made zero new requests. For a tool you would run repeatedly while editing a draft, that is the difference between usable and not, and it is keyed carefully enough that its own tests cover it.
MIT, TypeScript, built with esbuild to a single .mjs. 176 tests across 8 files, all green with no key — eight of them added for the fix above. Two runtime dependencies. Supports Jev or OpenRouter, chosen by which key is set.
One author, version 0.2.6.
The measurement holds: this really does ask every rule about every line, and we counted it rather than taking its word. The rule set is more useful than a generic “is this good writing” prompt, because each rule names a specific tic an agent can then fix concretely.
Use it on drafts. The one thing that undercut it — a clean report from a provider that never answered — was reported and fixed within hours, and a short answer set now stops the run with a count of what is missing.
Note the workflow, too: the output is a brief addressed to a coding agent, not a report for a human. If you were hoping for a linter you read yourself, this is not quite that.
For a tool that measures whether a question works at all before you trust its answers, see jev-calibrate; for another prose linter with a different split between code and judgement, Sniff Test.
See how it compares with other tools in Best Jev tools, tested hands-on.
Review updated Sep 23, 2026. Numbers quoted from the project are its author's own; we don't publish our own measurements of Jev.
dzhng/jevgrep
Finds code by what it does rather than what it matches: a CLI for coding agents that asks which files and which regions are relevant to a description.
Alex314618-create/JevRev
Puts an LLM and Jev in one workflow, with sift, loop and long modes, a TUI, and a CLI that can be pointed at any /v1/systemone host. English and Chinese.
uehaj/jev-semgrep
Grep by meaning: Jev scores each line against a description in any language, with AND, OR, and NOT. A single dependency-free Node file.
New Jev releases, pricing changes, and the best new projects, once a week. No spam; unsubscribe anytime.
Powered by Buttondown. See our privacy policy.