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

@lisgen/programmer

v0.1.0

Published

Lisgen Programmer: the Lisgen coding agent for your terminal

Readme

@lisgen/programmer

Programmer: the Lisgen coding agent for your terminal. It works with the model provider you choose; today the supported provider is a Tenzro node. It reads your project, writes and edits files, runs your tests, and shows its work — in a terminal, with your scrollback intact.

lisgen-programmer 0.1.2 · ladder routing
› add a retry with backoff to the upload path, and a test for it
Added `upload_with_retry` in src/upload.rs — three attempts, exponential
backoff, and it gives up on 4xx rather than retrying a rejection.
Verified: 12 passed in 0.31s
›
ask mode  /mode to change · /help                                      ladder

Install

npm install -g @lisgen/programmer

A native binary with a thin launcher. There is no JavaScript in the agent and no Node runtime is used once it starts — npm is the distribution channel, not the runtime.

Start

cd your-project
lisgen-programmer

The directory you launch from is the workspace — that is what it reads, edits and runs commands in. Use -C <path> to point it elsewhere.

Run lisgen-programmer doctor to see what it can reach and which model each rung resolves to. That is the first thing to check if something looks wrong.

Choosing a model provider

The agent runs the work on the model provider you choose, and by default that is the endpoint you name — not this machine. Today the supported provider is a Tenzro node. lisgen-programmer setup asks which provider, where it is and your key; the address goes in your config and the key in this computer's credential store:

lisgen-programmer setup

The node, given either way you were handed it:

  • an address — http://host:8545, or host:8545
  • a machine identifier — the node's own identity on the overlay, which needs no public IP, no DNS and no VPN between you and it

The key, if that node is gated.

You are asked even on a machine already running its own node. A node answering on this machine is not necessarily the one you were pointed at — a validator runs a node and serves no models — so the question is always put rather than assumed. Choose this machine at the prompt when your own node is the one you want.

To supply the key without storing it:

export LISGEN_PROGRAMMER_API_KEY=tnz_…

A key you paste is stored in ~/.lisgen/programmer/config.toml at mode 0600.

A gated node refuses an anonymous caller, so a missing key looks like a missing node. lisgen-programmer doctor tells the two apart: it reports the endpoint it reached and how many models it can see.

A complete config

Everything a network setup needs, in one file — ~/.lisgen/programmer/config.toml for your defaults, or lisgen-programmer.toml beside a project to override it field by field:

[provider]
kind = "tenzro"                     # the service that provides the models
url = "http://node.example.net:8545"  # address, or the machine identifier
prefer_local = false                # false: use the node above, even if one
                                    # runs here. Set true if your own node is
                                    # the one serving.
timeout_secs = 900                  # raise it if a slow model outlives a turn;
                                    # the default 300 shows up as
                                    # `transport error: error decoding response body`

[model]
sourcing = "network"
mode = "ladder"

[model.ladder]
l0 = { id = "qwen3.8-27b" }                           # reflex
l1 = { id = "qwen3.8-27b", max_tokens = 8192 }        # apply-edit
l2 = { id = "qwen3.8-27b", max_tokens = 32768 }       # agent loop, writes files
l3 = { id = "qwen3.8-27b", max_tokens = 32768 }       # planning

[orchestrator]
enabled = false                     # a small model that triages each request to
                                    # a rung. It runs on a *local* node, so it
                                    # is off by default; without it requests
                                    # enter the ladder by keyword matching.

Nothing here is required — the tool runs on defaults — but each line is one of the things that turns "it does not work" into "it works", so they are worth knowing before you need them.

Using it

| Key | | |---|---| | Enter | send | | Ctrl-J | newline — Shift+Enter too, on terminals that can report it | | ↑ ↓ | history; comes back to the line you were part-way through writing | | Ctrl-A Ctrl-E Ctrl-W Ctrl-U | start / end / delete word / clear line | | y a n | answer an approval, one keypress | | Esc | interrupt the running turn | | Ctrl-C Ctrl-D | clear the line, or exit when it is already empty |

| Command | | |---|---| | /mode plan\|ask\|accept-edits\|auto | how much it asks before acting | | /cost | what this session used | | /models | what the network is serving now | | /clear | start a fresh context | | /image <path> | attach an image to the next message | | /gauntlet <goal> | N builders → verify gate → adversarial critic, looped | | /autopilot <goal> | plan → per-milestone gauntlet → checkpoint, until done |

Permission modes run from plan (proposes, changes nothing) through ask (the default — approves each write and command) and accept-edits (files yes, commands ask) to auto.

Piped and non-interactive input falls back to a plain line-based loop, so this works unchanged in CI:

lisgen-programmer run "fix the failing test"

Choosing models

Configured in lisgen-programmer.toml in the project, or ~/.lisgen/programmer/config.toml for your defaults — project values win field by field.

  • Pinned — name one model and run everything on it.
  • Ladder — each role resolves to a rung: l0 autocomplete, l1 apply-edit, l2 the agent loop, l3 planning and hard reasoning. Rungs escalate on measured difficulty. Any rung can be pinned while the rest stay dynamic.
[model]
mode = "ladder"
sourcing = "hybrid"          # offline | local | hybrid | network

[model.ladder]
l2 = { id = "qwen3.8-27b" }        # the agent loop
l3 = { id = "qwen3.8-27b" }        # planning and reasoning

Output budgets

Each rung has an output token budget, defaulting to l0 256, l1 4096, l2 6144, l3 16384 — a reflex completion needs far less room than a planning turn. Raise it for a rung that writes whole files:

[model.ladder]
l2 = { id = "qwen3.8-27b", max_tokens = 32768 }

This matters more than it sounds. The budget cuts the reply off wherever it lands, and a tool call truncated mid-JSON cannot be parsed or salvaged: the turn reports no actionable output, retries, and truncates in the same place, until the repeat guard stops it. If a task loops on a trivial command instead of writing the file it just described, this is why. max_tokens is a ceiling, not a target — it does not make replies longer.

Which model on which rung

Put the fast model where a person is waiting and the slow one where thinking earns its keep. Measure rather than assume: the same 200-token reply took 4s on one model and 26s on another on the same hardware, and the difference is far more visible on l2 — which runs on every turn — than on l3.

A model reached through a remote engine also needs that engine to parse tool calls; without it the calls arrive as prose and the agent loop stalls. If one model works for chat but never seems to do anything, check that first.

sourcing is the one knob for where intelligence may come from: offline never leaves the machine, local refuses rather than reaching out, hybrid uses local where it fits, network always routes out.

Supported platforms

Linux (x64, arm64), macOS (Intel, Apple silicon) and Windows (x64, arm64) — the agent is portable and the command tool uses the platform shell (sh, or PowerShell on Windows).

Prebuilt binaries ship for Linux x64 and Windows x64. Linux arm64, Windows arm64 and macOS are not published yet: each is built on the architecture it runs on, and those builders are not part of this release. On those platforms npm install -g @lisgen/programmer installs the launcher and tells you there is no binary for your platform rather than failing obscurely.

Licence

Apache-2.0.