Jev SEO Dashboard — typed judgements on a live crawl

Jev MotherF*Cker Rank Me

Audit any site for SEO and AI-search visibility. A deterministic crawl feeds narrow typed questions to the Jev decision model, and the dashboard renders the probabilities as they land — not after the report.

npm version Node engine TypeScript React Express
$ npx jevseo

No account. No API key. No clone. Dashboard and API on one port — 8787.

The rule everything is built on
Code finds, Jev judges, the dashboard shows the probabilities.

Jev never writes prose. It answers narrow typed questions over crawled text and returns choice, score or noul answers with probabilities attached, which the code turns into ranked findings only where the answer is decisive. An LLM-authored finding is the defining failure mode of this category, so it is designed out rather than warned about.

The four layers

Each layer promises the next something specific. Click any layer to see its invariants and the traps that cost time rather than code.

Interactive. The same diagram as a static image: layers.png · full contract in LAYERS.md

Run it

The whole install is one command. It prints a URL and serves the dashboard and the API on the same port.

1Installed

npx jevseo
The package is scoped; the command is not. npm i -g jevseo puts a plain jev-seo on your PATH.

2Lifecycle

start --detach · status · stop · doctor
stop kills by PID from a pid file, never by process name.

3From a checkout

npm install · npm run dev
Dev is two ports with HMR: Vite 5173 + API 8787. Production is one.

4Optional only

opencode for deep research · uv/Python for the MCP · a GCP service account for Search Console. Without that key the agent is never granted the gsc tool, so it cannot source real traffic or keyword data — the audit still runs, on on-page mining alone.

How an audit runs

Eight stages. The model is never asked anything code can count for itself.

  1. CrawlBreadth-first, bounded by page count, depth and a wall-clock budget. Reads and honours robots.txt, seeds from sitemap.xml. Refuses private, loopback and link-local addresses so a pasted URL cannot reach an internal service.
  2. ExtractTitle, description, H1, headings, opening text, body text, word count, canonical, language, image alt coverage, link counts, noindex, structured data, viewport.
  3. Deterministic checks15 rule checks code can count for itself.
  4. Page judgementsOne request per page carrying every question for that page, fired concurrently behind a bounded pool. One item per request, because packing items has been shown to cost accuracy.
  5. Keyword passCode mines bigram and trigram candidates from titles, headings and body. Jev judges each: is it a real query, is a buyer typing it, what intent, which cluster, and does a page already serve it.
  6. Competitor passEach rival is crawled and judged on the same rubric, so the scorecards are comparable, plus a “worth copying” judgement and the single change that would most improve its AI citability.
  7. ThresholdsThree bands. Decisive answers become findings; the grey zone goes to a “needs a human” pile and is deliberately not acted on.
  8. StreamNewline-delimited JSON, so counters, the wall and the teardown tick as judgements land rather than after the report.

Three primitives, three bands

Both live in one reviewable file rather than being generated per call, because question design and threshold tuning move accuracy more than the choice of model does.

Primitives

choicescorenoul

choice picks one of up to 255 options and returns the full distribution · score is an ordered 2–10 rubric returning the probability-weighted mean · noul returns P(yes) for one proposition, used as a gate.

noul is a real primitive name, not a typo. Renaming it breaks the schema.

Bands

actreviewescalate

Decisive answers become findings. The grey zone is published, not hidden — and widening act to raise apparent coverage is the easiest way to make this product wrong.

What it will not tell you

The limits are part of the product, so they are stated rather than discovered.

No search volume, honestly

Jev carries no index, no volume data and no backlink graph, so there is no way to produce a monthly search count from this state — not approximately, not as an estimate. Keyword opportunity is computed in code from what is actually observable: on-page frequency, whether the term appears in headings, and how many pages carry it.

google-trends was removed rather than registered, because it has no official API and its “relative interest” index is exactly the pseudo-volume this product refuses to put in front of a paying customer.

VariableMeaning
JEV_DATA_DIRstate directory, default ~/.jev-seo
PORTport, default 8787 (--port beats it)
JEV_ENV_FILEexplicit .env path
JEV_WEB_DISTexplicit built-UI path
JEV_MODELjudge model, default jev-1.13-free
ZEN_API_KEYonly for the rate-limited jev-1.13

All mutable state goes in ~/.jev-seo. The install directory is never written to — under npx it is a cache npm garbage-collects.

Documentation

Six design contracts, plus the knowledge base an agent reads before touching this repo.