jev-lsp

WIP

LSP server for Jev rules. Pattern → typed decide on that line → normal diagnostics / code actions / code lens. Not chat.

What you can do

Setup

  1. Install (Rust ≥ 1.75):
    cargo install --git https://github.com/makefunstuff/jev-lsp --locked jev-lsp jev
  2. Key:
    export TYPESAFE_API_KEY=…
  3. Neovim ≥ 0.12 (nvim/ in the repo):
    ln -s /path/to/jev-lsp/nvim ~/.local/share/nvim/site/pack/jev/start/jev
    require('jev').setup({})
    Open a file. :checkhealth jev. Save.

Ambient: background decide → publishDiagnostics. If not sub-second, jev.checking (~500ms) until Warning/clear (8s budget). Not instant LSP.

omp: edit-inline may flash early OK until decide lands.

OpenCode 1.18 ambient unsupported — #21, upstream #17869. Use Neovim or VS Code.

Rule example

.jev/rules/no-unwrap-in-handlers.json

{
  "schema": "jev.rules/1",
  "rules": [
    {
      "id": "no-unwrap-in-handlers",
      "title": "Unwrap in a request handler",
      "text": "A handler must not unwrap: a bad request would take the worker down. Return the error instead.",
      "severity": "warning",
      "applies_to": ["**/src/**/*.rs"],
      "inspection": {
        "kind": "regex",
        "pattern": "\\.unwrap\\(\\)"
      },
      "judgement": {
        "question": "Is this unwrap in request-handling code that can fail on bad input?",
        "criteria": {
          "true": "ships in a handler / request path and the value is not proven safe",
          "false": "tests, docs, or an invariant on the surrounding lines covers it"
        },
        "min_probability": 0.85
      },
      "verb_hint": "fix"
    }
  ]
}

No pattern match → no decide call.

Docs