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

simba-agent

v1.18.0

Published

Simba Agent - a terminal coding agent that reads, edits and runs your code. Powered by OpenRouter.

Readme

Simba Agent

A terminal coding agent. Reads your code, edits it, runs commands, and keeps every conversation on disk. Runs on OpenRouter.

Requires Node.js 22 or newer (node --version).

npm install -g simba-agent
simba

One free API key is the whole setup — see below.

The API key

Simba looks for OPENROUTER_API_KEY in this order, first match wins:

  1. A real environment variable — CI, containers, export
  2. ./.env in the folder you run from — per-project override
  3. ~/.simba/.env — per-user, survives reinstalls and upgrades
  4. .env next to the installed package — for working on a checkout

Simba ships with no API key. Put your own in place once and it applies to every project on the machine:

mkdir -p ~/.simba && echo "OPENROUTER_API_KEY=your-key" > ~/.simba/.env

Free keys: https://openrouter.ai/keys. Nothing secret lives in this repository or in the published package — earlier versions bundled a fallback key, which was a mistake, and it was removed in 1.11.0.

Developing on a checkout

git clone https://github.com/sppideey/simba-agent.git
cd simba-agent && npm install && npm link

Layout

| File | Responsibility | | --- | --- | | llm.js | The only file that talks to a provider. Exports chat(messages, tools). | | tools.js | Tool schemas and implementations. Sandboxing, confirmation, truncation. | | session.js | Persistence to ~/.simba/sessions/. | | context.js | Token accounting and summarizing older turns. | | skills.js | Loading SKILL.md instruction packs. | | ui.js | Wordmark, transcript, spinner, markdown, prompts, errors. | | agent.js | The agentic loop and the CLI. |

Everything above llm.js speaks a provider-neutral message format:

{ role: 'user',      content: string }
{ role: 'assistant', content?: string, toolCalls?: [{ id, name, args }] }
{ role: 'tool',      toolCallId: string, name: string, content: string }
{ role: 'system',    content: string }

OpenRouter speaks the OpenAI wire format, so pointing SIMBA_BASE_URL at another compatible host works without code changes:

SIMBA_BASE_URL=https://api.groq.com/openai/v1 OPENROUTER_API_KEY=gsk-... simba

Models

/models lists a curated nine, every one probed with a real tool call before being listed. All are free; the paid balance is only a fallback.

| | Model | | | --- | --- | --- | | ★ | cohere/north-mini-code:free | default — built for code and UI work | | ★ | nvidia/nemotron-3.5-lightning:free | recommended — 1M context, for long sessions | | | nvidia/nemotron-3-super-120b-a12b:free | strong all-round, quick to answer | | | nvidia/nemotron-3-ultra-550b-a55b:free | deepest reasoning, 1M context, ~9s first token | | | nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free | small, reasoning tuned, overthinks | | | poolside/laguna-s-2.1:free | code specialist, large context | | | poolside/laguna-xs-2.1:free | smaller laguna, fastest to reply | | | google/gemma-4-31b-it:free | open general purpose, often congested | | | google/gemma-4-26b-a4b-it:free | sparse gemma, often congested |

/models opens an arrow-key picker: ↑↓ to move, Enter to select, Esc to cancel. The nine above sit at the top, followed by every other free tool-capable model OpenRouter currently serves, fetched live so the list does not go stale. /models <name> still accepts any model id directly.

The arrows only belong to the picker while it is open — everywhere else they scroll the conversation, which is also how the mouse wheel reaches the app.

Rate limits

OpenRouter meters requests, not tokens — roughly 1000/day on free models once the account has bought $10 of credit, ~50/day before that. One agent turn is several requests.

This is why compaction rarely fires now: with a 1M-token window the context window stopped being the binding constraint.

Free endpoints are shared, so a busy one returns a brief 429. Simba waits it out and resumes the same turn rather than erroring.

Tools

| Tool | Notes | | --- | --- | | read_file | Numbered lines, paged via offset/limit. | | write_file | Creates parent directories. For new files and full rewrites. | | edit_file | Exact-match replace. Fails on zero matches or two-plus matches. | | multi_edit | Several exact-match edits to one file in one call, all-or-nothing. | | list_dir | Directories first, then files with sizes. | | glob | **, *, ?, {a,b}. Newest first. Skips node_modules, .git, build dirs. | | grep | Regex over file contents, returns file:line: text. | | run_command | Runs without asking. Servers are detected and time out early with a hint; background: true keeps them running and returns the PID. Plan mode withholds it entirely. | | web_search | Searches the web via Tavily. Needs TAVILY_API_KEY — see below. |

Enabling web search

web_search is the one tool that needs its own key, and none ships with the package. Without it Simba says so and answers from training data instead.

Get a free key at https://tavily.com (1000 searches/month, no card), then:

mkdir -p ~/.simba && echo "TAVILY_API_KEY=tvly-your-key" >> ~/.simba/.env

Plan and build mode

Build (default) can edit files and run commands. Plan is read-only — the writing tools are withheld from the model entirely, so it investigates and tells you what it would change instead of changing it.

Toggle with Ctrl+B, or click the chip at the bottom right. Start in plan mode with simba --plan.

Clicking the chip needs the terminal to forward mouse clicks. It does not work on Windows — ConPTY does not pass mouse input to applications — so use Ctrl+B there.

Verification is enforced

Simba detects how your project checks itself at startup (npm test, cargo test, go test ./..., pytest, make test). If it changes code and then tries to finish the turn without running anything, it gets sent back to run the check and report the real result. "It should work" is not an outcome.

Rules the tools enforce, not the model:

  • Paths resolve inside the directory Simba started in. Anything outside needs a y/n.
  • Results are capped with a [truncated] marker: ~12k characters generally, ~48k for a file read, so the model can see a whole file before editing it. Override with SIMBA_MAX_TOOL_OUTPUT / SIMBA_MAX_FILE_OUTPUT.
  • edit_file never guesses. Ambiguous match means the file is left alone and the model is told how many matches there were.

Sessions

Saved to ~/.simba/sessions/<id>.json after every step — including mid-turn, after each tool result — so a crash or Ctrl+C loses nothing. Each file holds the complete message history plus id, created/updated timestamps, the project directory, model, token usage, and a title derived from your first message.

Startup is always a clean, empty session. Nothing from previous runs appears until you ask: /sessions lists them, /resume picks one up. Sessions from the folder you are in sort first.

Writes are atomic (temp file plus rename), so an interrupted save cannot leave a half-written session behind.

Context management

At 75% of the per-request token budget, the oldest turns are replaced with a summary rather than dropped, and the cut never falls between a tool call and its result. The session file keeps the full untruncated history regardless.

Set SIMBA_MAX_CONTEXT_TOKENS to force compaction earlier.

Skills

A skill is a folder with a SKILL.md:

---
name: code-review
description: Shown in the system prompt so the model knows when to reach for it.
---

Instructions go here. Only loaded when the skill is actually used.

Only names and descriptions go into the system prompt. The body is pulled in via the load_skill tool the moment a task matches, which keeps the base prompt small however many skills you add.

Ships with build-app, code-review, debug, frontend-design, and write-tests. Personal models can be added in ~/.simba/models.json, which lives outside the package and survives every upgrade. Drop your own into skills/, or into .simba/skills/ inside a project to override per-repo.

Commands

| Command | | | --- | --- | | /help | Command list | | /skills | List skills, marking which are loaded | | /new | Save the current conversation and start fresh | | /session | List past sessions and pick one to continue (/session 3 skips the picker) | | /clear | Clear the screen (history kept) | | /models | Show or switch model; also reports this session's token spend and live quota | | /web-search <query> | Research something and bring the results into the conversation | | /copy | Copy the last reply to the clipboard |

Ctrl+C interrupts a running turn. Ctrl+D saves and quits. Tab completes commands.

Flags

-m, --model <name>   model to use
-C, --cwd <dir>      run against another directory
    --debug          print stack traces on failure
-h, --help           usage

Errors

No bare stack traces. Every error states what was attempted, what failed, and what to try:

✗ Failed while sending a request to qwen/qwen3.6-27b.
  Per-minute limit exceeded for qwen/qwen3.6-27b — free again in 12s.
  → Wait 12s and send again — Groq's per-minute bucket refills continuously.
    /cost shows what is left.
  (rate_limit)

Distinguished: missing/invalid API key, per-minute vs per-day rate limits, network failure, malformed tool arguments, models that can't tool-call, hallucinated tool names, oversized conversations, file not found, permission denied, binary file, and corrupt session files. Transient 5xx and network failures are retried twice with backoff before you see anything.

Two failure modes are fed back to the model rather than shown to you, and it gets two attempts to correct itself: malformed tool arguments (invalid JSON, missing or wrong-typed fields) and hallucinated tool names rejected by Groq's server-side validator.

Tests

npm test

60 tests, no network or API key required.