npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

emp-code

v0.5.26

Published

EMP CLI - coding agent with full-screen TUI (ink, clickable tool output, mouse, plan mode, markdown, vision) and 18 providers. Runs great on any light PC / weak CPU / old motherboard. Sessions, context, effort, web search, background tasks, revert.

Readme

EMP CLI — coding agent for ANY PC

Built with Ink + React for a rich, interactive TUI. Made to run on any light PC — weak CPUs, old motherboards, low-RAM laptops — while still matching heavy agents feature-for-feature: full-screen TUI (clickable tool output, mouse, tables, markdown), vision (clipboard / image paste / website + active-tab capture), sessions, revert, web search, background tasks, and 18 LLM providers.

EMP CLI speaks the OpenAI-compatible /v1/chat/completions + /v1/models API, so every provider works the same: paste an API key, EMP CLI auto-fetches the model list from GET /models and caches it locally. Free models are sorted first and tagged (free) in the picker.

Free providers (no credit card)

All of these have a genuinely free tier and do not require a credit card. Add a key with /connect <provider> (or emp config), then pick a model.

| Provider | id | Free key | Free models | |---|---|---|---| | OpenCode Zen | zen | opencode.ai/auth | *-free (hy3-free, nemotron-3-ultra-free, laguna-s-2.1-free…) | | TokenRouter | tokenrouter | tokenrouter.com | Qwen 3.8 Max free right now | | OpenRouter | openrouter | openrouter.ai/keys | any model ending in :free (380+ models, lists w/o key) | | Groq | groq | console.groq.com/keys | fast Llama/Qwen, free tier | | Cerebras | cerebras | inference.cerebras.ai | fast Qwen/Llama, free tier | | Google Gemini | gemini | aistudio.google.com/apikey | generous free tier | | Hugging Face | huggingface | huggingface.co/settings/tokens | free inference (lists w/o key) | | Z.AI (GLM) | zai | z.ai | GLM flash/air free | | SiliconFlow | siliconflow | siliconflow.com | free open models | | NVIDIA NIM | nim | build.nvidia.com | free Nemotron + open models | | TrueSOTA | truesota | true-sota.com | AI API gateway (Bearer key) | | B.AI | bai | b.ai | AI API gateway (Bearer key) |

Connect examples:

/connect openrouter      :: then paste key, pick a :free model
/connect groq
/connect gemini
emp use openrouter/nvidia/nemotron-3-ultra-550b-a55b:free
emp --groq ask "hello"   :: force a provider for one turn

Note: a few free models are occasionally rate-limited (429) or down on the provider's side (500). EMP CLI auto-retries transient errors and tells you honestly which model/provider is at fault — it never silently swaps your model.

Why Ink + React (no native build)

EMP CLI uses Ink + React for its full-screen TUI — both are pure-JS packages (no compiled binaries, no native module). So it:

  • works on old CPUs without AVX1 / AVX2 and without Bun
  • runs on any Node.js 16+ (--no-warnings not required)
  • needs only a npm install (pulls pure-JS packages — no native build, no AVX)

Requirements

  • Node.js 16+. npm install once (pure JS, no native build — still no AVX/Bun).
  • The install.ps1 / install.cmd runs npm install for you.

Install

npm (recommended — Windows, macOS, Linux):

npm install -g emp-code

Windows one-liner (PowerShell):

irm https://raw.githubusercontent.com/saintdevzz/emp-cli/main/install.ps1 | iex

macOS / Linux one-liner:

curl -fsSL https://raw.githubusercontent.com/saintdevzz/emp-cli/main/install.sh | sh

No API key needed to start — just run emp and ask; add keys with /connect for other providers.

Quick start

emp setup              :: wizard asks for NIM + Zen keys, fetches models
emp ask "create a hello.py and run it"          :: agentic one-shot (uses tools)
emp --effort high ask "refactor this"          :: high effort
emp                                            :: agentic REPL (saves session, auto-names)
emp --zen ask "refactor this file"             :: force Zen provider for this turn
emp --nim --no-tools ask "plain chat, no tools" :: plain chat
emp sessions           :: list saved sessions
emp effort max         :: set effort globally

That's a coding CLI — not just chat

Like opencode, EMP CLI gives the model tools and lets it act as a coding agent. Every ask / chat turn is an agentic loop (up to 10 rounds):

  1. Model streams text or emits tool_calls (native OpenAI tools or fallback <emp_tool> JSON)
  2. CLI executes the tool locally and shows [tool] / [tool_result]
  3. Tool output is fed back as a tool message; the model continues
  4. Destructive actions and delete_file / git_commit ask for interactive confirmation (y/N) unless EMP_AUTO_APPROVE=1
  5. ask_question lets the model ask you questions mid-loop (single or multi-choice)

Tools (opencode-style toolkit + subagents + browser)

All tools use the same schemas the model sees (tools.getSchemas()) and run via lib/agent.js with permission checks. Inside the workspace everything is unrestricted; paths outside the workspace ask for permission (y/N) — set EMP_UNRESTRICTED=1 for the old unrestricted behavior.

| Tool | What it does | Outside dir? | Approval | |---|---|---|---| | list_files | List dir (default workspace, ignore node_modules/.git etc) | ask | — | | search_files | Search by filename or file content (walk) | ask | — | | grep | Regex grep — pattern (JS RegExp), include glob, case_insensitive | ask | — | | glob | Find files by glob **/*.js | ask | — | | read_file | Read file with offset/limit pagination | ask | — | | write_file | Create/replace file, mkdir -p | ask | if >16 KB overwrite | | edit_file | old_string→new_string patch | ask | — | | delete_file | Delete file | ask | always (y/N) | | run_command | spawn shell, captures stdout/stderr/exitCode, timeout | ask (cwd) | if destructive regex | | run_background | Long command in background, taskId, auto-notified | ask (cwd) | if destructive regex | | bg_status | List background tasks, or one's status + output | — | — | | git_status git_diff git_log git_commit | git operations | ask (cwd) | commit always | | ask_question | Model asks you questions (choices or open) | — | — | | todo_write | todos array (pending/in_progress/completed/cancelled) | — | — | | task_complete | Signals task fully done (hidden from the UI; the summary IS the final answer) | — | — | | wait | Sleep N seconds | — | — | | agent | Launch a background subagent with its own tools + prompt. Shows Agent(task) in the UI; parallel agents run concurrently | — | — | | agent_wait | Sleep until all (or given) subagents finish — results returned | — | — | | agent_status | List subagents / peek at one's output | — | — | | browser_open | Built-in zero-dep browser: open URL, get text/links/inputs/buttons | — | — | | browser_click | Click link/button by index (navigates) | — | — | | browser_type + browser_submit | Fill form fields and submit (GET/POST) | — | — | | browser_scroll browser_back | Scroll page text / go back in history | — | — | | web_search | DuckDuckGo search — no API key | — | — | | web_fetch | Fetch URL, redirects, HTML → text | — | — | | capture_website | Screenshot any URL (vision) | — | — | | capture_active_tab | Screenshot the user's open browser tab | — | — | | chrome_open | Open URL in real Chrome/Edge | — | — |

Plan mode (/plan or Tab): the system prompt switches to plan-first AND mutating tools (write_file, edit_file, delete_file, run_command, run_background, git_commit) are hard-blocked until the user approves and toggles plan off. Reads stay available so the AI can inspect before planning.

Destructive command regex covers rm -rf, git reset --hard, curl | sh, reg delete, etc.

Sessions, Context & Effort

  • Sessions lib/session.js:1 — every emp chat/ask saves to ~/.emp/sessions/<id>.json with name, provider, model, effort, messages. Auto-names from first user message (Hello world... → Hello world this is a test...) after 2 messages. List with emp sessions or /sessions in chat, new with /new, clear with /clear.
  • Context window lib/context.js:1 — estimates tokens as chars/4, limit 128k (200k for GPT-5/Claude/Gemini/Codex). Counts every message including assistant tool_calls and tool results, so the number reflects real usage. Shows right-aligned above each you> with a bar: ctx [####......] 42% 53.2k/128k. Auto-compacts at 80% by keeping first 2 + last 6 messages and inserting a [context compacted ...] summary (system prompt is regenerated, never stored).
  • Effort lib/effort.js:1 — none/low/medium/high/max (default medium). Controls system addendum + temperature. Set globally emp effort high or emp --effort high ask "..." or in-chat /effort high. Stored in ~/.emp/config.json settings.effort and per-session.

Interrupt the model (ESC ESC / Ctrl+C)

While the model is streaming, press ESC twice (within ~0.6s) or Ctrl+C to abort the in-flight request immediately. The socket is destroyed, [interrupted] is printed, any partial text is kept in the session, and you're back at the you> prompt. Wired via an abort controller (lib/http.js:makeCtl) threaded through providers.chat → streamRequest.

Reliability — auto-retry, honest errors, no forced fallback

  • Auto-retry: transient failures (429 rate limit, 500/502/503, timeouts, connection resets) are retried up to 3 times with exponential backoff. You'll see [retry 1/3] <reason> — waiting 1.6s. If a flaky provider recovers mid-retry, the turn just succeeds.
  • No forced fallback: EMP never silently switches your model. If muse-spark-1.2-contributor-free (or any model) keeps failing, you get an honest message naming the model and cause — e.g. ... returned 500 Internal server error (auto-retried). Their backend is failing this model right now — not an emp-cli bug. — and your chosen model stays chosen.
  • Partial-stream safety: if text already reached you, EMP does not retry (that would duplicate output); it only retries failures that produced no content yet.
  • Free-tier models on Zen (big-pickle, mimo-v2.5-free, etc.) are subject to OpenCode's own rate limits; a 429 means wait a bit or pick another model with /model <name>.

Web search & fetch (no key)

web_search hits DuckDuckGo's HTML endpoint — free, no API key, no credit card — and returns clean titles/URLs/snippets (ads filtered out). web_fetch follows redirects and converts HTML to readable text. The agent is told to search before guessing URLs.

Background tasks

run_background starts a long command (build/test/install/download) and returns a taskId instantly, so the agent keeps using other tools while it runs. You can run several at once. When one finishes it is injected back into the conversation automatically and the agent continues with the result — no polling needed. bg_status checks tasks on demand, and /bg lists them. If the agent is about to finish a turn while tasks are still running, it waits for them and reports their output.

Plan-first mode

/plan toggles plan mode: the agent produces a step-by-step implementation plan and waits for your approval before touching files. /plan on / /plan off set it explicitly, and /plan <task> plans that specific task right away. Plan mode is stored per-session and shown in the header as [plan mode].

Full-screen TUI with clickable tool output

emp chat opens a full-screen TUI (like opencode / Claude Code) built on Ink + React — no Bun, no AVX, so it runs on old/slow machines.

  • Click any tool chip (bash / edit / write / thinking) to expand or collapse its output — bash stdout, a +/− diff for edits/writes, or the model's reasoning. Clicking is handled by the TUI's own mouse parser, so no escape-sequence garbage ever leaks into the screen.
  • Scroll with the mouse wheel or PgUp/PgDn. Up/Down recall your previous prompts (shell-style history); long input scrolls horizontally so the cursor stays visible.
  • Queue messages while the AI is busy — type and hit Enter and it's queued; a queued: line shows the latest plus (+N other messages), and they're sent in order when the reply finishes.
  • Select / copy text — hold Shift and drag (this bypasses mouse capture in Windows Terminal and most terminals). Or set EMP_NO_MOUSE=1 to turn off mouse capture entirely (you keep native selection but lose click-to-expand and wheel-scroll).
  • Tab toggles plan / build mode (indicator in the header).
  • Enter sends, Backspace edits, Left/Right move the cursor, Ctrl+L redraws.
  • ESC (or Ctrl+C) interrupts the agent while it works; Ctrl+C on an empty input quits, Ctrl+C twice force-quits, Ctrl+D quits.
  • A status bar shows provider/model, plan mode, context %, todo progress, and running background tasks.
  • /show still prints the last turn's hidden output; /todo shows the agent's todo list.

Set EMP_NO_TUI=1 to force the classic inline UI (useful over SSH or in basic terminals). In the classic UI, mouse expansion is opt-in via EMP_MOUSE=1 and /show is the universal fallback. Everything degrades gracefully on terminals without mouse support.

Commands

emp                                Agentic chat (tools on, streaming, saves session)
emp ask "your prompt"              One-shot (also saved as session)
emp chat --effort high             High effort (none|low|medium|high|max)
emp models [nim|zen]               List models (auto-fetches + caches)
emp refresh [nim|zen]              Re-fetch models
emp config                         Manage both providers' keys + default models
emp setup                          First-run wizard (both providers)
emp use <nim|zen>[/model]          Set active provider/model
emp workspace [path]               Show or set workspace dir
emp sessions                       List saved sessions (~/.emp/sessions)
emp effort [level]                 Show/set effort (none|low|medium|high|max)
emp info                           Show config + tools + workspace + context
emp doctor                         Node/arch + tool count + probe endpoints
emp help

Flags: --nim / --zen force provider; --effort <level>; --no-tools disables tools.

In-chat REPL:

 /exit, /clear, /new, /sessions, /models, /model <name>, /effort [level], /compact
 /info, /tools, /workspace [path], /help, /connect [nvidia|opencode]
 Context bar above input (e.g. "ctx [####......] 42% 53.2k/128k"), auto-compact at 80%
 While the AI is generating: press ESC twice (or Ctrl+C) to interrupt it

API keys & auto-fetch

Stored in plain text at ~/.emp/config.json (lib/config.js:15). Prompts are not masked (portable plain Node). Or use env vars (take precedence):

NVIDIA_API_KEY=...          NIM (nim)
OPENCODE_ZEN_API_KEY=...    OpenCode Zen (zen)
TOKENROUTER_API_KEY=...     TokenRouter
OPENROUTER_API_KEY=...      OpenRouter
GROQ_API_KEY=...            Groq
CEREBRAS_API_KEY=...        Cerebras
GEMINI_API_KEY=...          Google Gemini
HF_API_TOKEN=...            Hugging Face
ZAI_API_KEY=...             Z.AI (GLM)
SILICONFLOW_API_KEY=...     SiliconFlow

On setup/config/refresh (or first ask/chat when a key is present), EMP CLI does GET <provider>/models with Authorization: Bearer <key> (OpenRouter + Hugging Face also list with no key), sorts IDs with free models first, and saves providers[<id>].models + modelsFetchedAt to ~/.emp/config.json. Use emp refresh <provider> to force update. All providers go through the same lib/providers.js OpenAI-compatible client.

Notes

  • Default provider is nim until emp use zen.
  • Streaming + tool calls handled in lib/providers.js:132 (accumulates delta.tool_calls by index and falls back to <emp_tool> parsing via extractToolRequest() lib/providers.js:41).
  • Agent loop is in bin/emp.js:141 (runAgent) — up to 10 rounds, feeds tool messages back to the model.
  • Auto-approve for CI: EMP_AUTO_APPROVE=1 emp ask "..."
  • No lock-in: you can still use any NIM/Zen model as plain chat with --no-tools.