@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 ladderInstall
npm install -g @lisgen/programmerA 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-programmerThe 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 setupThe node, given either way you were handed it:
- an address —
http://host:8545, orhost: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:
l0autocomplete,l1apply-edit,l2the agent loop,l3planning 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 reasoningOutput 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.
