The built-in nREPL stays minimal (clone/describe/eval/load-file/close) but now
composes a middleware stack so a library can add the heavier features (sessions,
interruptible-eval, completion, lookup) without bloating core.
- A middleware is (fn [handler] (fn [request] ...)); request carries :reply (a
thread-safe send that adds id/session) plus the wire fields. List them in
deps.edn :nrepl/middleware (symbols -> a middleware fn or a vector of them);
jolt.nrepl composes them over the built-in handler.
- Public seam: respond, evaluate, register-ops!, new-session, err-msg.
- Per-connection send lock so middleware replying from other threads don't
interleave bytes. describe advertises built-in + registered ops.
deps.clj surfaces :nrepl/middleware; jolt.main passes it to the server. Built-in
behavior unchanged when no middleware is declared. Runtime, no re-mint.