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:
    ---
    applies_to: **/*.ts, **/*.tsx
    ---
    
    A Python-only diff never loads your TypeScript rules; a .tsx change 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 choice question 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 score question rating severity (Minor โ†’ Moderate โ†’ Major โ†’ Blocking), and a choice question 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

  1. 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.
  2. Manually โ€” Jev: Analyze changes command, or the sync icon in the sidebar's title bar.
  3. In CI, on a pull request โ€” scripts/review-pr.ts runs 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 same src/ modules as the editor extension โ€” no separate implementation to keep in sync. Requires the TYPESAFE_API_KEY secret; re-runs on the same PR don't repost a comment already there for the same rule. Skips fork PRs (no pull_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):

FileApplies toRules
jev/typescript.md**/*.ts139
jev/python.md**/*.py56
jev/css.md**/*.css47
jev/go.md**/*.go42
jev/shell.md**/*.sh29
jev/markdown.md**/*.md29
jev/html.md**/*.html35
jev/react.md**/*.tsx33
jev/scss.md**/*.scss28
jev/yaml.md**/*.yml, **/*.yaml21
jev/json.md**/*.json20

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

  1. Command Palette โ†’ Jev: Set Jev API key (stored in VS Code SecretStorage; alternatively set TYPESAFE_API_KEY in the launching environment). Without a key, results are labeled OFFLINE MOCK.
  2. Open the Jev Code Check icon in the Activity Bar.
  3. 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

SettingDefaultDescription
jevCodeCheck.rulesDirjevDirectory of *.md rule files, relative to the workspace root.
jevCodeCheck.autoAnalyzeOnSavefalseOpt-in: analyze as you edit and on save (throttled to 1/sec).
jevCodeCheck.debounceMs1200Inactivity delay before auto-analysis; floored at 1000ms.
jevCodeCheck.maxDiffChars20000Diff text cap sent to Jev; excess is disclosed, not silently dropped.
jevCodeCheck.maxFileContextChars8000Per-file content cap.
jevCodeCheck.maxTotalContextChars40000Total file-context cap across all changed files.
jevCodeCheck.maxRulesPerRequest20Upper 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.