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

weezcode

v0.1.0

Published

WeezCode — a terminal-based AI coding agent for any OpenAI-compatible chat-completions endpoint (Ollama, LM Studio, OpenRouter, etc.).

Readme

WeezCode

A terminal-based AI coding agent in the style of Claude Code / Codex / Cursor, backed by any OpenAI-compatible chat-completions endpoint — Ollama, LM Studio, OpenRouter, vLLM, llama.cpp, or your own self-hosted gateway. Run it locally, point it at a model, and it reads, edits, runs, and reviews code with a per-tool permission model that defaults to safe.

Why WeezCode

  • Provider-agnostic. Works with any OpenAI-compatible endpoint. Tested against Ollama, OpenRouter, LM Studio, and llama.cpp.
  • Permission-first safety model. Every mutating tool (write_file, edit_file, bash) goes through an explicit permission prompt with { once, always, session, deny } verdicts. Hard-rejected patterns (rm -rf /, sudo, curl|sh, heredocs) never run, even if the user approves.
  • Out-of-cwd is not auto-allowed. cat /etc/passwd from the bash tool is downgraded to "ask" even though cat is in the allowlist. All file tools use fs.realpath so symlinks can't escape the sandbox.
  • Open source, no telemetry, no phone-home. Reads ~/.weezcode/config.json and your LLM endpoint, and nothing else. See SECURITY.md for the threat model.
  • Same tool surface as Claude Code, fewer surprises. read_file, write_file, edit_file, list_directory, search, bash, plus vision (!img <path>), snippets (/snippet), MCP (weezcode mcp), and --json for scripting.

Features

  • Interactive REPL with streaming responses (Ink + React) and live thinking display
  • 6 tools the model can call: read_file, write_file, edit_file, list_directory, search, bash
  • Safety-first bash: read-only commands auto-run, anything else prompts; destructive patterns are hard-rejected; out-of-cwd reads are downgraded to "ask"
  • Unified diff in the write_file / edit_file permission prompt — see exactly what changes before you approve
  • Permission prompts for write_file and edit_file — nothing on disk changes without your approval; "All writes (this session)" option to grant blanket write permission for the rest of the session
  • Headless mode (-p) for scripts and CI, with --json NDJSON event stream
  • Slash command autocomplete — type / to see matching commands, ↑/↓ to navigate, Enter to execute
  • Model picker/model opens a live list of models from /v1/models
  • Token usage in the status row, with per-turn + cumulative counts
  • Retry with backoff on transient API errors (network, 429, 5xx)
  • MCP support (weezcode mcp list|add|remove|test) — register stdio MCP servers and let their tools be called by the model
  • Vision!img <path> attaches an image to a user message
  • Snippets/snippet save <name> <body> for reusable prompts
  • Shell completionsweezcode completion bash | zsh | fish

Requirements

  • Node.js 20+ (the bin/weezcode shim refuses to run on older versions)
  • ripgrep (rg) on $PATH — used by the search tool
  • An OpenAI-compatible chat-completions endpoint

Install

From npm (recommended for users)

npm install -g weezcode
weezcode             # starts the REPL

From source (recommended for contributors)

git clone https://github.com/akanda/weezcode.git
cd weezcode
npm install      # builds dist/ via the `prepare` script
npm link          # exposes `weezcode` on your PATH

From Docker

docker build -t weezcode .
docker run -it --rm \
  -v $PWD:/workspace \
  -v ~/.weezcode:/home/node/.weezcode \
  weezcode

The Dockerfile is multi-stage (Node 20 slim, tini, ripgrep). See Dockerfile for details.

Shell completions

# bash — add to ~/.bashrc
eval "$(weezcode completion bash)"

# zsh — add to ~/.zshrc
eval "$(weezcode completion zsh)"
# Then: autoload -U compinit && compinit

# fish — add to ~/.config/fish/config.fish
weezcode completion fish | source

Configuration

Resolution order: CLI flag → env var → ~/.weezcode/config.json → built-in default.

| Setting | CLI flag | Env var | Default | |----------------|--------------|----------------------|----------------------------------| | API key | (none) | WEEZCODE_API_KEY | (empty) | | Base URL | (none) | WEEZCODE_BASE_URL | http://localhost:11434/v1 | | Model | -m <name> | WEEZCODE_MODEL | llama3.1:8b | | Profile | (none) | WEEZCODE_PROFILE | (none — uses config.json) |

WEEZCODE_PROFILE=<name> swaps the config file to ~/.weezcode/config.<name>.json so you can keep multiple side-by-side (e.g. work, home, local-ollama). All other env vars and CLI flags still apply on top.

Option A: in-REPL setup (recommended for first run)

Just run weezcode and type /setup. The REPL walks you through base URL, API key, and model, tests the connection, and saves to ~/.weezcode/config.json. Changes take effect immediately — no restart needed.

Option B: non-interactive setup (for scripts / Docker)

weezcode --setup --setup-url https://your-tunnel.example.com/v1 \
                --setup-key  sk-your-key \
                --setup-model qwen2.5:14b

Or with plain readline prompts:

weezcode --setup
# Base URL: https://your-tunnel.example.com/v1
# API key:  sk-your-key
# Model:    qwen2.5:14b
# Saved to ~/.weezcode/config.json.

Option C: write the config file directly

~/.weezcode/config.json example (mode 0600 recommended for the API key):

{
  "apiKey": "sk-your-cloudflare-tunnel-key",
  "baseUrl": "https://weez-llm.example.com/v1",
  "model": "qwen2.5:14b"
}

The API key is sent as both Authorization: Bearer <key> and a custom x-api-key: <key> header (the Cloudflare-tunnel-friendly form).

Option D: taste file (per-user preferences)

Drop a markdown file at ~/.weezcode/taste.md with key: value lines for non-secret preferences:

# My WeezCode preferences
show_thinking: off
quiet: on
system_prompt: |
  Always respond in haiku. Be terse.

Recognised keys: show_thinking (on/off), quiet (on/off), system_prompt (free-form block, appended to the built-in prompt). Lines starting with # and blank lines are ignored. Missing file → use defaults.

Usage

weezcode                                    # interactive REPL
weezcode "what's in this directory?"        # one-shot (deprecated — use -p)
weezcode -p "read package.json"             # headless, prints result, exits
weezcode -m llama3.1:70b                    # override model for this run
weezcode --list-models                      # GET /v1/models and print IDs
weezcode -p "hi" --no-thinking              # strip <think>…</think> from output
weezcode -p "hi" --show-thinking            # print reasoning to stderr as it streams
weezcode -p "fix the bug" --diff            # after running, print git diff to stderr
weezcode -p "summarize" --tool-choice none  # pure chat, no tool calls
weezcode -p "..." --system-prompt-file p.md # custom system prompt
weezcode -p "..." --json                    # NDJSON event stream for piping
WEEZCODE_VERBOSE=1 weezcode -p "hi"         # stream tool calls to stderr
weezcode -q                                 # REPL: hide banner and help row
WEEZCODE_PROFILE=work weezcode -p "..."     # use a separate config profile
weezcode install-hooks                      # write .git/hooks/pre-commit (typecheck + tests)
weezcode doctor                             # diagnose common setup problems (rg, config, model, taste)
weezcode completion bash                     # print a shell completion script (bash | zsh | fish)
weezcode mcp add fs npx -y mcp-filesystem /path  # register an MCP server
weezcode mcp list                           # show registered MCP servers
weezcode mcp test fs                        # verify the MCP handshake + tool discovery
weezcode --model-smart big --model-fast small # multi-model routing (first/tool → smart, length → fast)

REPL shortcuts

  • Enter — send the message
  • Tab — in the / command menu, fill the input with the highlighted command
  • ↑/↓ — navigate the command menu (or scroll the model picker)
  • Esc — close the command menu or model picker
  • Ctrl+C — first press aborts the current stream; second press within 1500ms exits
  • Ctrl+D — first press prints a hint, second press within 1500ms exits

Slash commands

Type / to open the autocomplete menu, then use ↑/↓ to navigate and Enter to execute. Some commands can also be typed directly.

| Command | Effect | |--------------------|-----------------------------------------------------------------------------------------| | /help or ? | Show the full command list in-REPL | | /setup | Re-run the setup wizard (changes take effect immediately) | | /model <name> | Switch the model for the current session (no name → open the model picker) | | /model smart <n> | Set the smart model for the multi-model router (first turn, after tool turns) | | /model fast <n> | Set the fast model for the multi-model router (length-continuation turns) | | /thinking | Toggle the visibility of the model's <think> reasoning blocks | | /reset (or /new)| Clear the conversation log and token usage. Config is preserved. Refused mid-stream. | | /undo | Revert the most recent write_file or edit_file. Single-slot snapshot — second mutating tool replaces it. | | /stats | Show session stats: turn count, tool call counts, total tool time, wall time, tokens | | /snippet <name> | Show a saved snippet | | /snippet save <name> <body> | Save a snippet to ~/.weezcode/snippets.json | | /snippet list | List all saved snippets | | /snippet delete <name> | Delete a saved snippet | | /copy | Copy the most recent assistant message to the clipboard (falls back to a temp file) | | /refresh | Explain how to ask the model to re-read files (no in-memory cache to clear) | | /exit | Quit WeezCode |

/setup and /model are also accessible mid-stream (they don't queue). All commands appear in the conversation history like normal messages.

Token usage

The status row shows cumulative token usage and a per-turn delta:

WeezCode · model qwen3-coder:30b · cwd ~/proj · thinking on · 12.3k tok (in 8.0k / out 4.3k) · last +1.0k

If the model doesn't report usage (some local Ollama builds), the line is omitted.

Model thinking

Reasoning-capable models (Qwen, DeepSeek, etc.) emit their chain-of-thought inside <think>…</think> blocks. WeezCode detects these in the stream and renders them in a dimmed · thinking block above the visible answer, updated in real time. Toggle with /thinking or --no-thinking (headless). Three block formats are recognised: <think>…</think>, <antml:thinking>…</antml:thinking>, and OpenAI's <|channel|>analysis<|message|>…<|end|>.

By default the full content (with thinking) is kept in the message log so the model sees its own reasoning on the next turn. --no-thinking strips it from both the rendered output and the log. Unclosed think blocks are stripped from the log automatically (so the model doesn't see its own dangling <think> on the next turn).

Vision

Attach an image to your message by prefixing with !img <path> (or !image <path>). Multiple images are supported. The path must be absolute; local files are base64-encoded and sent as image_url data URLs. You can also pass an http(s):// URL directly. Supported file types: .jpg, .jpeg, .png, .gif, .webp, .bmp (max 10 MB each).

!img /tmp/screenshot.png what's wrong with this UI?
!img a.png !img b.png compare these two layouts
!img "~/Desktop/photo.png" describe this picture
!img https://example.com/diagram.png walk me through this

The model can describe, transcribe, or reason about the image. The image is sent alongside your text as a vision message; the image isn't stored on disk by WeezCode.

Bash permission model

| Class of command | Behavior | |-------------------------|-----------------------------------------------------------| | ls, cat README.md, pwd, git status, … | Auto-runs (read-only) | | cat /etc/passwd | Prompts (out-of-cwd reads can't auto-run) | | Anything else | Prompts: once / always (session) / deny | | rm -rf /, sudo, curl|sh, mkfs, dd of=/dev/, redirects, … | Hard-rejected, never runs |

Multi-command strings (a && b, a; b) are classified per-segment. If any segment is dangerous, the whole command is denied. After approval, only the first segment runs (the rest gets a [weezcode: only the first segment ran] warning so silent drops are visible). Out-of-cwd file reads (cat /etc/passwd) are downgraded to "ask" even when the command itself is allowlisted.

Permission model for write_file and edit_file

Both tools ask for explicit permission before touching disk. The "always" key is the absolute file path (narrower than bash, which keys on the first command token — see the table above). "Always allow write to foo.ts" only auto-allows that one file.

Development

npm run dev          # tsx-watched run of src/cli.tsx
npm run typecheck    # tsc --noEmit
npm run lint         # eslint
npm run format       # prettier --write
npm test             # node --test over test/*.test.ts
npm run build        # tsc → dist/

See CONTRIBUTING.md for project conventions and how to add a tool or slash command.

Limitations (v1)

  • Sessions are in-memory only. Every REPL launch starts fresh — there's no -c / --continue / --resume yet (JSONL persistence is v2). Use the messages log inside the REPL for the current session.
  • No sub-agents. MCP support is at the foundation level (weezcode mcp list|add|remove|test); full tool-registry integration is a follow-up.
  • Vision: read-only. You can attach images to a message via !img <path> (or !image <path>); the model can describe them. The tools themselves don't produce images, so model output can't include image generation.
  • Bash multi-segment runs only the first segment after a prompt approval (deliberate safety tradeoff — the model is expected to issue separate bash calls for follow-ups). A safety note is appended to the output.
  • Single binary, no plugins.

Audit

A full production audit lives in AUDIT.md, with items graded 🔴 P0 / 🟠 P1 / 🟡 P2 / 🟢 P3. The P0 ship-blockers are all closed; the remaining items are polish and observability.

Changelog

See CHANGELOG.md for the full release history and the versioning policy. We follow semver.

For maintainers

The maintainer's runbook for cutting a release is in docs/PUBLISHING.md. The short version:

  1. One-time setup: create an npm account with 2FA, claim the weezcode name (a placeholder 0.0.1 is fine), enable Trusted Publishing on npmjs.com, create a GitHub npm-publish environment with required reviewers.
  2. Cut a release: merge to main with a green CI, then git tag -s v0.X.Y && git push --tags. The publish workflow runs the full check suite, requests your approval in the npm-publish environment, and publishes with provenance.
  3. Verify: from a clean shell, npm install -g weezcode and run weezcode --version + weezcode doctor.

For a deeper look at how releases flow (release-please, Trusted Publishers, why we don't use NPM_TOKEN), see the runbook.

License

MIT — see LICENSE.