跳到正文
Hacker News (official RSS)(github.com)·· 5 小時前AI 評分53

Shev,支援 DeepSeek v4.1 與本地 MLX 的決策生成工具

DeepSeek v4.1 flash on OpenCode pretty good

AI 導讀

Shev 是一款可直接使用的決策生成工具,支援 DeepSeek v4.1 與本地 MLX 執行。

  • - 輸出格式。
  • JSON,包含 actionable、take_action、confidence、generated_response,方便直接讀取或整合至工作流程。
正文

shev — decisions, without the hype

A simple Jev-like decision maker. Without the hype.

Hand it one whole message — an email, a ticket, a review, a doc, whatever you pasted out of the support queue — and tell it what you want done with it. It hands back one decision, as JSON:

{
  "actionable": "Reply to Sam and cc finance about the overdue March invoice.",
  "take_action": true,
  "confidence": 95,
  "generated_response": "Hi Sam, ... (the reply, written out)"
}

That's the whole thing. No agents. No orchestration. No prompt engineering. No five-hundred-token preamble to memorise. One message in, one decision out, in a file you can just read.

  • Whole message, judged once. It doesn't chop the thing into paragraphs and it doesn't go line by line. One message, one decision.
  • You say what you want. It asks before it answers, and what you want done is what drives the reply it writes.
  • The answer has a shape. actionable (a string), take_action (a boolean), confidence (an integer, always in [34, 100]). No tuple you have to guess at.
  • Runs on your Mac if you want. DeepSeek over the network, or a small ternary MLX model sitting right there on the machine. Switch whenever.
  • It writes it all down. Decisions pile up in responses.json as response1, response2, … and other models can read them over MCP.

Install

One line, copy-pasteable:

curl -fsSL https://raw.githubusercontent.com/aditauqir/shev/main/install.sh | bash

Then type shev. The installer uses a user bin directory already on PATH where possible. Otherwise it adds a small, removable PATH block to your shell profile; open a new terminal and type shev—no manual shell edits needed.

Prefer npm?

npm install -g @noorslvt/shev
shev

This installs the package @noorslvt/shev, with the terminal commands shev and shev-cli. The unscoped npm registry name shev belongs to an unrelated project; do not use npm install -g shev for this tool. You can also install straight from the repo without the registry:

npm install -g git+https://github.com/aditauqir/shev.git

Both installers prefer a matching prebuilt release and otherwise build with Rust (installing the minimal Rust toolchain if necessary). npm runs a postinstall step that fetches the right binary or builds it; macOS/Linux are supported by the npm launcher, and Windows users can use WSL.

Recent npm releases gate install scripts. If your install is skipped, shev tells you what to run; you can also fix it up front:

# if npm blocked the install scripts:
npm approve-scripts @noorslvt/shev   # or:
npm rebuild -g @noorslvt/shev --foreground-scripts

Got Rust already? Same thing, just as short:

cargo install --git https://github.com/aditauqir/shev

Uninstall

For full cleanup, whether installed with curl or npm, close other running shev sessions first:

shev --uninstall --dry-run  # preview paths; delete nothing
shev --uninstall            # confirm before removal
# or: shev --uninstall --yes

This removes registered shev binaries, its saved keys/config, local model data, tracked chat records, unchanged tracked shev MCP registrations, and the exact PATH blocks added by its installer. A full npm-backed uninstall also runs npm's package removal. Modified binaries/profile blocks, externally managed weights, host recovery backups, unrelated host settings, non-chat metadata in export files, source checkouts, and shared tools/caches (Rust, Node, uv, Codex, OpenCode) are not deleted.

You can also remove the npm package directly:

npm uninstall -g @noorslvt/shev

This removes the npm package and its binaries. Modern npm does not execute uninstall hooks, so it cannot also remove persistent settings/models/history or external MCP registrations. Use shev --uninstall for full cleanup; it handles the npm package removal too. Persistent npm data deliberately lives outside the package so a normal npm upgrade does not erase private keys, history, or model downloads. No background uninstall watchers or npm overrides are installed.

What you need

  • Best for local use: Apple Silicon — M1 or newer, 16 GB of RAM and up.
  • 8 GB will fit the local model too, but it's tight.
  • Everything else: runs anywhere with a DeepSeek API key. No Mac required.

Only the local model cares about the Mac. It runs on MLX, and MLX is Apple Silicon only, so "run it on your machine" means "run it on a Mac". Point shev at a DeepSeek key instead and the work goes over the network — then it builds and runs on any platform Rust does.

Quick start

shev
  1. Bonsai is the default. Install it through /model if needed; no API key is required. DeepSeek is optional through /model; its key is stored at ~/.config/shev/config.json as 0600.
  2. Type or paste the whole message. enter sends it, ctrl+j drops a new line in the middle of a multi-line one.
  3. Say what you want done with it — "draft a short reply", "does this need me today", "where's the risk here".
  4. Read the decision. enter starts the next one, or click ▸ open responses.json in Finder and go look at the file.

After the first run it's just: run shev, type, done.

The TUI

The home/start screen has a white ASCII wordmark directly over the wallpaper, without a background box or JSON pane. Once a chat starts, two windows appear:

  • Left, the model output. Every decision as a clean field list. The prompt box sits flush at the foot, with its mode line ("Build · bonsai (local) · …") on the last row.
  • Right, this turn's JSON only. The raw record for the decision you are on, so you can read the file without leaving the screen. Drag across JSON text to select it; releasing the mouse copies exactly the selection and shows ✓ copied to clipboard at the top center. The mouse wheel scrolls the JSON independently. /copy json copies the complete record, including off-screen text.

Text panels use #0F0E08 over the dimmed photo wallpaper. Type / for commands: Panels are inset from the terminal edges. Skills/tools menus show names only; long menus scroll around the selected row instead of clipping it off-screen.

shev home screen

shev decision view

Command What it does
/file <path> Load a message from a file (drag-and-drop works too)
/copy [json] Copy selected JSON or the last response; json copies the complete record
/key Enter or replace the DeepSeek API key
/cancel Abort the request in flight
/clear Clear the visible chat and input; keep saved history
/reset Confirm clearing the chat, all saved history, loaded context and counters; keep keys/models
/help Show the keybindings
/model Pick the model and manage it (keys, install, uninstall)
/home Back to the home screen (the transcript is kept)
/history Jump through the decisions so far
/mcp Install, remove, or report the local MCP bridge
/skills Load existing skill guidance; /skills off clears supporting context
/tools [server] Connect to a registered MCP server and inspect read-only tools
/tool server/tool <JSON> Call a read-only tool and attach its result to the next decision
/plugins Show host-plugin compatibility limits
/quit Leave

Handy keys:

Key What it does
enter Send the message, then the intent
ctrl+j Newline inside the box
ctrl+t Switch the model (DeepSeek ↔ Bonsai)
ctrl+h Open the history (same as /history)
ctrl+d in history Confirm deletion of only the selected saved entry
ctrl+y Copy selected JSON, or the last generated response
ctrl+c Quit

/clear starts a fresh chat view; /history can reopen retained records. /reset and history deletion default to cancel in their confirmation menus. Confirmed changes update the responses file, so MCP clients see them too.

Models

/model switches between two backends and manages each one.

DeepSeek — the secondary, explicitly selected remote option; needs an API key. Options: enter a new key, remove the stored key, or cancel.

Bonsai (default) — prism-ml/Ternary-Bonsai-2-2B-mlx-2bit, a small ternary model that runs on Apple Silicon through MLX. Options: install it from the internet (about 1.2 GB, into ~/.local/share/shev/models) or uninstall it.

The Bonsai pack ships its own loader, because its weights can't be loaded by stock mlx-lm/mlx-vlm (they report Unsupported model type: prism_hadamard_qwen35). So shev runs the pack's bundled runtime in a resident worker, using uv with the pack's pinned requirements. Repeated requests in the same session reuse the loaded model; a one-shot loader remains as fallback. Nothing listens on a port. The first local request installs the MLX stack into a uv environment, which can take a few minutes.

Output-head experiments

This pack ties its output to language_model.model.embed_tokens.as_linear; there is no separate language_model.lm_head. Its native 2-bit operation requires the pack's Hadamard transform. Changing a bits parameter alone is not a valid conversion.

tools/bench-bonsai-head.py compares native 2-bit with a correctly repacked 4-bit output head in memory, leaving input embeddings and installed files untouched. Run with the pack's runtime/requirements.txt, after a local shev request has created ~/.local/share/shev/models/shev_bonsai_worker.py:

uv run --python 3.12 --with-requirements \
  ~/.local/share/shev/models/Ternary-Bonsai-2-2B-mlx-2bit/runtime/requirements.txt \
  python tools/bench-bonsai-head.py

With the current deterministic prompt, one local run measured 1.55 ms/head and 669 ms/decision for native 2-bit, versus 2.29 ms/head and 734 ms/decision for repacked 4-bit. Both scored 6/6 action labels on a tiny smoke test; an earlier prompt/sampled baseline scored 3/6. This is not evidence of general accuracy, and the improvement is from the prompt/sampling changes, not from repacking. Repacking cannot recover precision already lost in the 2-bit checkpoint. Native 2-bit therefore remains the default. Hardware, prompts and output length affect these timings; existing explicit provider selections are preserved.

MCP

Shev's MCP server lets another assistant read your saved decisions. It does not run Bonsai/DeepSeek or edit your files. No API key, OAuth login, terminal, network port, or separately started TUI is required: the MCP host starts shev as a subprocess and talks JSON-RPC over stdin/stdout.

1. Choose the history file

Save at least one decision using an explicit file path, for example:

shev --file "$HOME/shev-responses.json"

Inside that TUI run /mcp install (or /mcp → install). This writes a descriptor under ~/.config/shev/mcp/ and registers the executable and absolute history path in an existing global OpenCode config, with a private backup. /mcp status reports the registration; /mcp uninstall removes shev's own unchanged registration. It does not delete your decisions.

2. Connect OpenCode or Codex

For OpenCode, reconnect shev from /mcps or restart the client after installation. Alternatively, register it explicitly from a shell (replace the executable path if you built from source):

opencode mcp add shev --global -- "$HOME/.local/bin/shev" --mcp --file "$HOME/shev-responses.json"
opencode mcp list

The equivalent OpenCode V2 configuration is:

{
  "mcp": {
    "servers": {
      "shev": {
        "type": "local",
        "command": ["/absolute/path/to/shev", "--mcp", "--file", "/absolute/path/to/responses.json"],
        "enabled": true
      }
    }
  }
}

For Codex, add this to ~/.codex/config.toml (or your CODEX_HOME config), replacing the paths, then restart Codex and check codex mcp list:

[mcp_servers.shev]
command = "/absolute/path/to/shev"
args = ["--mcp", "--file", "/absolute/path/to/responses.json"]

Both shev --mcp and shev-cli --mcp work. For a source build, use /absolute/path/to/repository/target/release/shev after cargo build --release. Do not put shell expressions such as $(pwd) inside a JSON/TOML command array.

3. Ask the host assistant to use shev

Example prompts in OpenCode/Codex:

  • “Use shev's latest_decision tool and summarize my most recent decision.”
  • “Use shev's search_decisions with query invoice and limit 10.”
  • “Read response2 using shev's get_decision tool.”
Tool Example arguments Result
list_decisions {"limit": 20} Most recent records, oldest first
latest_decision {} Latest saved record
get_decision {"key": "response2"} or {"index": 2} One saved record
search_decisions {"query": "invoice", "limit": 10} Matching saved decisions

Resources are shev://decisions (all records) and shev://decisions/latest (latest record). Reads use the file afresh, so decisions saved by an open TUI become available without restarting the MCP process.

Troubleshooting: unknown option --mcp means the host is launching an old TUI binary. Update/rebuild the exact executable in the MCP command and reconnect shev. Current releases dispatch --mcp before terminal setup. If connection succeeds but no decisions appear, check that the host and TUI use the same absolute history path. Starting shev --mcp manually will wait quietly for protocol input; this is normal, not a frozen chat window.

Reuse existing skills and tools

/skills reads existing SKILL.md files from Codex, Claude, shared ~/.agents/skills, ~/skills, OpenCode's XDG config directory, and ancestor project .opencode, .agents, and .codex skill folders, plus local skill directories configured in OpenCode. It loads guidance into memory; it does not install, edit, or execute skill scripts.

/tools reads MCP registrations from Codex's config.toml and OpenCode's global/project JSON or JSONC, including V2 mcp.servers. CODEX_HOME and XDG_CONFIG_HOME are respected. Selecting a server connects and lists tools; selecting a tool shows its argument schema and prepares /tool server/tool {}. Edit the arguments, then enter to call it. Successful results become reference context for the next decision; /skills off unloads them. Supporting context does not replace the user's original intent in history.

Only tools with readOnlyHint: true and without destructiveHint: true can be called. Unknown/mutating tools are blocked, not silently approved. MCP annotations are declarations from your trusted server, not a security sandbox; only use servers you trust. Starting a configured server can run its startup code. Calls have time/output limits and cannot request sampling or approvals. Stdio and streamable HTTP (JSON/SSE) are supported. Configured headers and environment-based tokens are reused without logging them; host-managed OAuth credentials are not copied. An OAuth-only server reports an authentication requirement rather than claiming success.

The top of the right pane names the loaded skill or successfully called tool and its source. Integration identity is also stored with its decision. Merely discovering/selecting a server is not reported as a successful tool call.

OpenCode's configured JavaScript plugins are listed with compatibility notices. Host-specific plugins cannot run natively in shev; they require their host runtime. Their MCP interfaces, where registered, can be used through /tools. shev never rewrites host configuration during discovery or tool use. Explicit /mcp install is separate and backs up configuration before registration.

CLI

The TUI is the friendly front door. The line CLI is shev-cli and it's meant for pipes:

echo "Your invoice is 30 days overdue." | shev-cli -i "draft a polite reminder"
shev-cli "Should I ship this today?" -i "answer yes or no and why"
shev-cli --mcp                       # serve decisions over MCP on stdio
Option Meaning
-c, --once <message> Judge one message and exit
-i, --intent <text> What you want to do with it
-f, --file <path> Where decisions are appended (default responses.json)
--mcp Serve the recorded decisions over MCP (stdio)

Useful environment variables:

Variable Meaning
DEEPSEEK_API_KEY Use this key instead of the stored one
SHEV_RESPONSES_FILE Where decisions are appended
SHEV_INTENT Default intent for a non-interactive run
SHEV_MODELS_DIR Where local models live
SHEV_HOME Managed npm state root (set automatically by the npm launcher)
SHEV_BONSAI_MAX_TOKENS Local worker token cap (default 256; cold fallback 2048)
SHEV_BONSAI_STREAM 1 enables worker token-delta protocol messages
SHEV_BONSAI_TEMPERATURE Local sampling temperature (default 0, deterministic)

The footer shows token usage and the last decision's elapsed milliseconds. The resident worker reports real local token counts; the cold fallback has no usage metadata and reports zero rather than guessing. The concise summary and generated response remain alongside the JSON. A measured warm run took about 750 ms versus 2500 ms including initial model loading—not a claim of Jev's sub-100-ms latency. Malformed local decisions receive at most two format-correction retries; usage includes those attempts. Retries can add latency and still fail rather than silently recording invalid JSON.

Where things live

Path What it is
~/.config/shev/config.json API key and the selected model (0600)
responses.json The decisions, appended as response1, response2, …
~/.local/share/shev/models/ Downloaded local models
~/.config/shev/install.json Installer-owned binaries/PATH blocks and history paths for scoped cleanup

The npm launcher isolates its config, default history, and models under ~/.local/share/shev-npm/state/ (or $XDG_DATA_HOME/shev-npm/state/) instead of the paths above. This data survives npm upgrades. Shell and MCP integrations still read your existing host configuration without copying credentials. Explicit --file/SHEV_RESPONSES_FILE paths stay where you chose them and are tracked for explicit shev --uninstall cleanup.

License

Apache-2.0. See LICENSE.