Jev Realtime Code Check
September 18, 2026 ยท View on GitHub
A VS Code / Cursor extension that checks your local Git changes against your own coding rules, using TypeSafe AI's Jev model. It watches your diff, not your whole repo โ only the rules relevant to the file types you actually touched get sent, and only new violations introduced by your change are flagged.
๐บ Demo video: https://youtu.be/goVDTUd7-J0
What it does
- Reads a directory of Markdown rule files (default
jev/), one#heading per rule. - Each rule file can declare which files it applies to via a frontmatter
header:
A Python-only diff never loads your TypeScript rules; a--- applies_to: **/*.ts, **/*.tsx ---.tsxchange only loads your React rules. No frontmatter means "applies to everything." - Collects the combined staged + unstaged diff for tracked files
(
git diff HEAD), plus surrounding file content, as context. - Sends one
choicequestion per applicable rule to Jev in as few requests as possible โ batched adaptively by measured payload size (not a fixed count), since diff/file context size varies far more than rule count does. - For anything Jev flags as a violation, a smaller follow-up request
asks two more questions per violation: a
scorequestion rating severity (Minor โ Moderate โ Major โ Blocking), and achoicequestion picking which specific added block of code is responsible. - Real line numbers for that block come from parsing the diff's own hunk headers โ never invented by the model. Clicking a violation jumps straight to that file/line; it also shows up as a Problems-panel diagnostic.
- Results are grouped in the sidebar by outcome (Violations and errors on top and expanded; Compliant/Not applicable collapsed at the bottom, since with hundreds of rules those are mostly noise, not signal), sorted within Violations by severity.
- Works offline too: with no API key configured, a labeled OFFLINE MOCK mode runs simple heuristics instead of a live call, so you can still see the UI flow.
Three ways it runs
- Automatically, whenever code changes settle โ opt-in
(
jevCodeCheck.autoAnalyzeOnSave, off by default with an explicit consent dialog). Debounced to fire once edits pause for ~1s, so it naturally fires when an LLM agent finishes a burst of edits, not mid-stream. This is backed by a filesystem watcher, not just editor events โ an external tool (an AI coding agent, a formatter, anything) writing files directly to disk is picked up even if that file was never opened in an editor tab, which a plain "on save" hook would miss. - Manually โ Jev: Analyze changes command, or the sync icon in the sidebar's title bar.
- In CI, on a pull request โ
scripts/review-pr.tsruns the identical rule-matching + Jev pipeline against a PR's committed diff (base...HEAD) and posts a GitHub review comment on each violation it can localize to a file/line. See.github/workflows/jev-review.yml. It reuses the samesrc/modules as the editor extension โ no separate implementation to keep in sync. Requires theTYPESAFE_API_KEYsecret; re-runs on the same PR don't repost a comment already there for the same rule. Skips fork PRs (nopull_request_target, to avoid running PR code with base-repo secrets).
Why "rules as data"
Rules are just Markdown you write and version-control like any other
project file โ no plugin code, no schema beyond a heading and an optional
frontmatter line. This repo ships 479 example rules across 11 file
types as a starting point/stress test (TypeScript, React/TSX, CSS, Sass,
Markdown, Python, Go, JSON, YAML, HTML, and shell), each with a Good/Bad
code example, spanning style/convention, language-specific "gotchas" (real
semantic footguns โ .forEach not awaiting async, YAML's NO parsing as
false, Go's pre-1.22 loop-variable capture), and per-language performance,
security, and UI/accessibility best practices (path traversal, ReDoS,
shell=True injection, SQL string-building, focus-visible styles, layout
shift, touch target size, and more):
| File | Applies to | Rules |
|---|---|---|
jev/typescript.md | **/*.ts | 139 |
jev/python.md | **/*.py | 56 |
jev/css.md | **/*.css | 47 |
jev/go.md | **/*.go | 42 |
jev/shell.md | **/*.sh | 29 |
jev/markdown.md | **/*.md | 29 |
jev/html.md | **/*.html | 35 |
jev/react.md | **/*.tsx | 33 |
jev/scss.md | **/*.scss | 28 |
jev/yaml.md | **/*.yml, **/*.yaml | 21 |
jev/json.md | **/*.json | 20 |
Delete what you don't need, edit anything, or write your own โ a rule file is just:
---
applies_to: **/*.ts
---
# No console statements
Code must not contain `console.log`, `console.debug`, or `console.info`
calls. Use a proper logger, or remove them before committing.
Good:
```ts
logger.info("Config loaded", { path });
```
Bad:
```ts
console.log("Config loaded", path);
```
Install
npm run install:extension
Builds, packages, and installs into whichever of cursor/code is on your
PATH, in one step. Or manually: npm run package produces a .vsix, then
Extensions view โ ... โ Install from VSIX....
The extension ships with no rules โ that's intentionally left to
whoever installs it. If your workspace has no jev/ directory yet, the
sidebar's empty state is clickable and runs Jev: Create example rule,
which scaffolds a single starter jev/example.md (applies_to: **/*) to
edit from, rather than requiring you to write the format from scratch.
Setup
- Command Palette โ Jev: Set Jev API key (stored in VS Code
SecretStorage; alternatively set
TYPESAFE_API_KEYin the launching environment). Without a key, results are labeled OFFLINE MOCK. - Open the Jev Code Check icon in the Activity Bar.
- Run Jev: Analyze changes, or enable automatic analysis via Jev: Toggle automatic analysis for this workspace (opt-in, with an explicit confirmation dialog explaining what gets sent).
Configuration
| Setting | Default | Description |
|---|---|---|
jevCodeCheck.rulesDir | jev | Directory of *.md rule files, relative to the workspace root. |
jevCodeCheck.autoAnalyzeOnSave | false | Opt-in: analyze as you edit and on save (throttled to 1/sec). |
jevCodeCheck.debounceMs | 1200 | Inactivity delay before auto-analysis; floored at 1000ms. |
jevCodeCheck.maxDiffChars | 20000 | Diff text cap sent to Jev; excess is disclosed, not silently dropped. |
jevCodeCheck.maxFileContextChars | 8000 | Per-file content cap. |
jevCodeCheck.maxTotalContextChars | 40000 | Total file-context cap across all changed files. |
jevCodeCheck.maxRulesPerRequest | 20 | Upper bound on rules per request; actual batches are sized smaller automatically if diff/file context is large. |
Project layout
src/ Extension source (TypeScript)
test/ Unit tests (node:test)
jev/ Rule files for this repo's own code (dogfooding)
demo-fixture/ Small React app + jev/ rules for a guided before/after demo
playground.ts Scratch file for exercising rules against real edits
Development
npm install
npm run typecheck
node --import tsx --test test/*.test.ts
npm run package # produces the .vsix
See INSTALL.md for a step-by-step install/demo walkthrough, and
demo-fixture/BEFORE_AFTER.md for a guided edit โ violation โ revert
script.