Skip to content
MrJev

jev-shell-history

Fish-style zsh autosuggestions, ranked by Jev from your recent history.

View on GitHub →

Hands-on review

Fish-style zsh autosuggestions ranked by Jev, including plain-English ones. It works well, but it sends your recent shell history on every keystroke.

Good for

  • Recalling a command you half-remember by describing it instead of its spelling
  • Adding fuzzy, meaning-based suggestions on top of zsh's own history search
  • A small, readable example of splitting exact rules and judgment between code and Jev

Watch out for

  • Your recent shell history goes to TypeSafe on every keystroke, with no redaction
  • One billed request per keystroke that changes the line; there is no debounce
  • No LICENSE file, although package.json says MIT

Tested Sep 20, 2026 at 4b2b75d26c0c · Node 24 and zsh 5.9 in Docker, with a real Jev key and a fabricated 15-command history

How we reviewed this: we ran the plugin and its CLI in Docker on Node 24 with zsh 5.9, using a real Jev key and a fabricated 15-command history. We ran the unit tests, the type check, the end-to-end suite that drives a real interactive zsh, and we captured one outgoing request with a local stand-in server to see exactly what gets sent.

What it does

jev-shell-history, by mrnugget, gives zsh the grey inline suggestions Fish users know, but ranked by Jev instead of by prefix matching. As you type, it reads your most recent distinct commands from the history file, asks Jev which one you are most likely in the middle of typing, and shows the winner after the cursor with its probability. Press → or ^E at the end of the line to accept it.

The interesting part is the second mode. When nothing in your history starts with what you typed, the plugin sends everything and lets Jev rank it, so a description can stand in for a command you half-remember:

% last 5 commits  ⇢ git log --oneline -5  [0.990]
% run the tests   ⇢ python3 -m pytest -q  [0.900]

Those are results from our own run, on a history we wrote ourselves.

How the work is split

One request per keystroke carries two questions about the same state: a Choice over the candidate commands, whose probabilities are the ranking, and a Noul asking whether any candidate completes what you typed. The Noul matters because Choice probabilities always add up to one, so without it the least-bad option would always win, however irrelevant.

Everything exact stays in code: reading and de-duplicating the history file, detecting literal prefix matches, the thresholds, and the ordering. Jev only makes the judgment call. It’s one of the clearest small examples of that split we’ve reviewed.

Using it

  • The tests pass. 21 unit tests and the type check passed. The end-to-end suite, which types into a real interactive zsh in a pseudo-terminal, passed all 7 of its checks with a live key: suggestions appear, typing along a suggestion doesn’t re-request, → and ^E accept and run the command in both emacs and vi keymaps, nonsense yields nothing, and a stale answer is discarded when the line changes mid-request.
  • One failure was ours. The end-to-end suite first failed on the replace-mode check because our container had no UTF-8 locale, so the ⇢ marker came through as escaped bytes. With LANG=C.UTF-8 it passed. Worth knowing if you run the suite in a minimal container.
  • The gate works. Typing qzxv wpl produced no suggestion: the Noul came back low and the Choice spread out, which is exactly the case the two-question design is built for.
  • Prefix mode can skip the request. With a single literal prefix match, the plugin suggests it with no call at all.

Permissions and data

This is the part to think about before installing it.

  • Your history leaves your machine. In fuzzy mode the whole recent window — 100 distinct commands by default — is sent to TypeSafe in one request. We confirmed this by pointing the client at a local server and reading the payload: every command in our test history was in it, verbatim. In prefix mode only the matching commands are sent. Either way, what you have typed so far is sent too.
  • Nothing is redacted. Shell history is a bad place to keep secrets, but plenty of real histories contain a token pasted into a curl command, a connection string with a password, or an internal hostname. The plugin has no filter, no allow-list, and no way to exclude an entry. If your history holds anything you would not paste into a third-party API, don’t install this as it stands. (A first step would be zsh’s own HIST_IGNORE_SPACE, which keeps space-prefixed commands out of the history file entirely.)
  • One request per keystroke. Every buffer change past two characters starts a new request; the previous local process is killed, but a request already in flight has been sent and is billable. There is no debounce, so fast typing means many requests. We don’t publish Jev’s prices; work out your own from your typing habits before leaving it enabled all day.
  • Your key lives in the environment. TYPESAFE_API_KEY is read from the environment, as the README says. Setting it in .zshrc puts it in a file you may well be syncing somewhere.
  • The debug log. With JEV_DEBUG_LOG set, every buffer and every response is appended to that file in plain text, including the commands. Useful for debugging, worth turning off afterwards.

Maintenance

A single commit on September 18, no issues, no LICENSE file, although package.json declares MIT. It reads as a weekend experiment that a lot of people noticed, not a maintained product.

Verdict

As an experiment it lands: the two-question design is neat, code keeps everything that should be exact, and in the handful of queries we tried, the plain-English mode picked the command we meant. The gate that suppresses nonsense actually held.

The cost is the data flow. Autosuggestion is a feature you leave on all day, which means a continuous stream of your recent shell history going to TypeSafe, unfiltered, one request per keystroke. That’s a reasonable trade on a machine whose history you’d happily publish, and not one anywhere near a production or client machine. If the project adds a redaction list and a debounce, that calculation changes.

For other command-line tools that send less, see our Best Jev Tools roundup, and what each tool sends for the data-flow comparison.

See how it compares with other tools in Best Jev tools, tested hands-on.

Review updated Sep 20, 2026. Numbers quoted from the project are its author's own; we don't publish our own measurements of Jev.

More in Command-Line Tools

jevgrep (dzhng)

★ 3.1k▲ 239

dzhng/jevgrep

Finds code by what it does rather than what it matches: a CLI for coding agents that asks which files and which regions are relevant to a description. Unrelated to the JevGrep above, which has the same name.

TypeScriptReviewed

webctl

★ 163▲ 1

dorkitude/webctl

Search CLI for agents: results from up to three backends are scored by Jev against your query and an explicit --goal, and only the relevant ones reach the agent's context. Its benchmark excludes an arm it could not observe.

GoReviewed

sys1grep

★ 150

uehaj/sys1grep

Greps by meaning rather than pattern, scoring every line against a description and combining meanings with AND, OR and NOT; a single dependency-free Node file. Japanese and English. Formerly jev-semgrep.

JavaScriptReviewed

Get new Jev projects every week

New Jev releases, pricing changes, and the best new projects, once a week. No spam; unsubscribe anytime.

Powered by Buttondown. See our privacy policy.