Command line
The same pipeline as the web app, on your own machine, with your own key. Your spending limit is your approval.
Install
You need Python 3.12 or newer, git 2.50.1 or newer, Graphviz (diagrams) and Pango (PDF export):
| System | Command |
|---|---|
| macOS | brew install git graphviz pango pipx |
| Ubuntu | sudo add-apt-repository ppa:git-core/ppa, then sudo apt-get install git graphviz libpango-1.0-0 libpangoft2-1.0-0 pipx (Ubuntu's own git is older than 2.50.1) |
| Debian | sudo apt-get install graphviz libpango-1.0-0 libpangoft2-1.0-0 pipx, plus git 2.50.1 or newer (check git --version; Debian's own may be older) |
| Windows | Use WSL (Ubuntu) and follow the Ubuntu line |
Then install Nehemvix in its own environment, from PyPI:
pipx install aelsha-nehemvix
nehemvix --version
Update with pipx upgrade aelsha-nehemvix; remove it with pipx uninstall aelsha-nehemvix.
Check that your machine has what a run needs:
nehemvix doctor
It checks Python, git (2.50.1 or newer), Graphviz and PDF export, and lists which key variables are set. It ends
with ready (exit code 0) or names what is missing (exit code 1).
Your first guide
Put your key in an environment variable, never on the command line. By default each provider reads its usual
variable (GEMINI_API_KEY, OPENAI_API_KEY, ANTHROPIC_API_KEY, VERTEX_API_KEY, OPENAI_COMPATIBLE_API_KEY,
AZURE_AI_API_KEY, BEDROCK_API_KEY); --key-env names another.
export ANTHROPIC_API_KEY=...
nehemvix run https://github.com/pallets/itsdangerous --provider anthropic --model claude-haiku-5-5 --cap 0.50
It prints a job id, the estimate, then one line per step while it reads the code and writes the guide, and ends with the grounding score and the cost. In our tests this repository (46 files) took about three minutes and $0.06 on claude-haiku-5-5, and the three guides for a one-file repository cost $0.01 on gpt-6-luna.
On the command line there is no approve button: the run continues only if the estimate's upper end is within
--cap. Otherwise it stops before spending anything and says so; run again with a higher --cap, or give the
model's price with --price-in and --price-out (both) if it has no listed price. Before that, it prints the estimate,
for example estimate: $0.018 to $0.038 (likely $0.024), about 19 model calls, about 2 min, and when it stops it says
which --cap is enough.
What you get
Everything is written to ./out (--out to change it), named after the repository:
| File | What it holds |
|---|---|
owner_repo.beginner.md (and .senior.md, .architect.md) |
One guide per audience you asked for, in Markdown, with diagrams and citations to exact lines |
owner_repo.assessment.md |
The readiness checklist: CI, tests, logging, licences and more, each pass, warn or not applicable, with evidence. Automated signals, not an audit |
owner_repo.report.json |
Machine-readable: each guide's grounding score and checks, cost and tokens by stage, the estimate, the checklist |
owner_repo.beginner.pdf and others |
With --format html,pdf,docx,pptx,drawio: the same exports as the web app, in its default style (drawio only when the guide has diagrams) |
Progress, checkpoints and remembered file summaries live in ~/.nehemvix (--data). A second run on the same
repository reuses the summaries of files that haven't changed, so it costs less.
Exit codes
For scripts and CI, the exit code tells you what happened; the last line says why.
| Code | Meaning |
|---|---|
0 |
Done: the guides and the report are written |
1 |
Stopped or failed: the estimate was above --cap or the price is unknown (without --json; see 4), the repository couldn't be read, or the --out folder can't be written (checked before anything is spent) |
2 |
Wrong input: an invalid link, an unknown provider or audience, a missing key variable, an unknown job id |
3 |
Paused: a model's limit ran out or the key was refused. Nothing is lost; resume it (after finish: finish it again later or on another model) |
4 |
With --json only: stopped before spending, because the estimate is above --cap or the model has no price. A person must approve a higher cap (the result's needed_cap_usd) or give a price. Without --json this stop is 1, as before |
130 |
Stopped with Ctrl-C. Nothing finished is lost; resume it |
With --json, the same outcome is in the result's status and exit_code, and next_action says what to do
(schema).
For AI agents and scripts
Add --json to run, resume, finish, ask or doctor: stdout then carries exactly one JSON object, valid against the
JSON Schema, even when the input is wrong, and every human message goes to stderr.
nehemvix run https://github.com/pallets/itsdangerous --provider openai --model gpt-6-luna --cap 0.50 --json
--events jsonl(withrun,resumeandfinish) streams progress on stderr, one JSON object per line.run --estimate-only --jsonfetches the repository, prints the estimate and stops; nothing is spent.nehemvix list,status,outline,section,searchandreadinessread the guides in--data, for people or, with--json, for programs.nehemvix mcpserves those guides to an AI agent as a local MCP server over stdio.
Frameworks, the tools and the spending rules: Use Nehemvix from AI agents.
Every provider
| Provider | Example |
|---|---|
| Gemini | --provider gemini --model gemini-3.8-flash (reads GEMINI_API_KEY) |
| Vertex AI | --provider vertex --location global --service-account-file key.json, or an API key in VERTEX_API_KEY |
| Claude | --provider anthropic --model claude-haiku-5-5 (reads ANTHROPIC_API_KEY) |
| OpenAI | --provider openai --model gpt-6-luna (reads OPENAI_API_KEY) |
| OpenAI-compatible | --provider openai_compatible --base-url https://openrouter.ai/api/v1 --model nvidia/nemotron-3.5-super-vl:free --key-env OPENROUTER_API_KEY ($0 on a free model) |
| AWS Bedrock | --provider bedrock --region us-east-1 --model us.amazon.nova-micro-v1:0 (reads a Bedrock API key from BEDROCK_API_KEY), or an access key pair with --aws-key-id-env MY_ID --aws-secret-env MY_SECRET |
| Microsoft Foundry | --provider foundry --base-url https://<resource>.openai.azure.com --model <deployment> --key-env AZURE_AI_API_KEY |
Keys and credentials: Set up your AI provider.
Private repositories
Give a read-only access token in a variable you name; it is used for one fetch at the pinned commit and never stored:
export GIT_TOKEN=... # GitHub: a fine-grained token with read access to the repository's contents
nehemvix run https://github.com/your-org/your-repo --provider openai --model gpt-6-luna --git-token-env GIT_TOKEN
GitHub, GitLab and Bitbucket need no user name; for another host add --git-user NAME. The job is marked private: its
file summaries are never shared with other jobs' memory, and dependency lookups on public registries are off.
Ask a question
Ask about a finished guide; the answer comes from the guide's own index, written by the model you choose, with its sources and any names it couldn't find in the code:
nehemvix ask <job-id> "How are signed values given a timestamp?" --provider openai --model gpt-6-luna
In our test, questions about pallets/itsdangerous cost $0.0003 on gpt-6-luna and $0.0009 on claude-haiku-5-5.
Options
| Option | Meaning |
|---|---|
--skills beginner,senior,architect |
Which guides to write (default: beginner) |
--length concise |
Concise, standard or detailed sections |
--cap 1.00 |
Spending limit in US dollars for the whole job |
--preset gemini_free, --rpm, --rpd, --tpm |
Your model's limits. Presets: gemini_free, gemini_paid, vertex_project, openai_tier, anthropic_tier, bedrock_on_demand, foundry_deployment |
--thinking medium, --analysis-thinking none |
Thinking while writing, and while reading |
--temperature 0.2 |
0 to 1, where the model accepts it |
--price-in, --price-out |
Your price per million tokens, for a model without a listed price (give both) |
--fallback "" |
No fallback model on the same key |
--cache-policy same_model_only |
Reuse remembered file summaries only from the same model (default: from any model) |
--format html,pdf,docx,pptx,drawio |
Also write each guide in these formats |
--git-token-env NAME, --git-user NAME |
A private repository's read-only token, from a variable you name |
--out, --data |
Where the guides go, and where progress and memory live |
--aws-session-env NAME |
Bedrock with temporary credentials: the variable holding the session token |
--json |
One JSON result on stdout (run, resume, finish, ask, doctor and the read commands) |
--events jsonl |
Progress events on stderr, one JSON object per line (run, resume, finish) |
--estimate-only |
With --json: estimate and stop, spending nothing (run) |
Pauses and resuming
If a model's limit runs out or the key is refused, the run pauses (exit code 3) and prints the job id and the
command to continue. Continue later, on the same or another provider:
nehemvix resume <job-id> --provider openai --model gpt-6-luna --cap 0.50
Finished work is reused, never paid for twice: in our test, a job paused on a daily request limit with Claude finished
on gpt-6-luna with a grounding score of 100. Stopping a run with Ctrl-C works the same way: resume it by its job id.
Use the same --data folder you ran it with. Resuming a job that already finished changes nothing; if it has missing
sections, it says so and points to nehemvix finish.
Finish the missing sections
When a guide finished with sections unwritten (the cap ran out while writing, or the model declined a section), write only those, on the same or any other provider:
nehemvix finish <job-id> --provider anthropic --model claude-sonnet-5-5 --cap 3.50
It lists the missing sections and prints the estimate next to what was already spent. --cap is for the whole job,
so it must cover what was spent plus the most this finish can cost; without it, the job's own cap applies. When the cap
is too low it stops before spending and says which cap is enough (exit code 1). Nothing finished is read or paid for
again: in our test, a guide that stopped at its $2.00 cap with 9 sections missing was finished on Claude Sonnet with 15
calls (9 sections, 6 corrections) for $0.59, and its architect guide went from a grounding score of 52 to 99. The
guides are written to --out again. Exit codes: 0 every section written (or nothing to finish), 1 stopped before
spending or sections still missing, 2 no such job or a job that isn't finished (use resume), 3 a model's limit
ran out (finish again later or on another model). With --json, a stop before spending is 4 (needs_approval, with
the needed_cap_usd that would do), and a limit that ran out is paused with next_action finish.
How a run works: stages, checkpoints and state
A run is one LangGraph workflow, the same one the web app runs. The stages, in order:
- ingest fetches the repository at a pinned commit (no checkout), removes secrets and flags text aimed at AI tools, all before any model call.
- estimate computes the cost range and the number of model calls, then pauses for approval (see below).
- agents runs the optional add-on agents that are enabled, if any, once the estimate is approved.
- map summarises files in parallel batches. A gate after the batches routes back to re-plan only the files still unfinished if a model's limit stopped some of them.
- reduce summarises folders from those file summaries.
- synthesize plans the sections each audience gets.
- write writes the sections in parallel, with a gate afterwards that does the same for sections still unwritten.
- assemble builds each guide, evaluate checks names, paths and citations in code and scores the grounding,
index makes the guide searchable (for
ask,searchandnehemvix mcp), and publish finishes the job.
Where state lives. Everything is under --data (default ~/.nehemvix): the job database nehemvix.db, the
workflow's checkpoints in checkpoints.db next to it, and the stored guides in objects/.
The guides you asked for are copied to --out.
Finished work is never redone or billed twice. Every paid unit (a file summary, a folder summary, a written
section) is saved in the job_units table of that database under a stable key when it completes, and the call ledger
records each model call's cost. On resume, after a Ctrl-C, or on another model, a stage first reads those units and
only calls the model for what is missing. Switching provider or model therefore costs only the remaining work, and the
stored units are reused whichever model made them.
Approval. The workflow stops at the estimate until someone approves it. In the web app that is a button. On the
command line there is no approve flag: the --cap is the approval. If the estimate's upper end is within --cap, the
run continues on its own; if not, it stops before spending anything (exit code 1, or 4 with --json). With
--json --estimate-only it always stops there, so you can read the estimate and decide.
Quota pauses. When a model's daily or per-minute limit runs out or its key is refused, in-flight units finish or
are deferred, nothing is lost, and the job is marked paused (exit code 3). It prints the files and sections done, the
amount spent, and the command to continue. Wait for the limit to reset and run nehemvix resume <job-id> again, or
continue now on another provider or model with --provider, --model and --key-env; the gates re-plan only the
unfinished work, sized for the new model. Use the same --data folder.
Finishing a done guide. A job that ended with sections unwritten is not resumed: nehemvix finish
estimates and writes only those sections, again on any provider or model, and refuses to start if the job's cap can't
cover the worst case.
For the design behind this, see How it works, the architecture and pause and resume an agentic AI pipeline.
Common messages
| Message | What to do |
|---|---|
error: set OPENAI_API_KEY in the environment, or name another with --key-env |
Export the key variable, or name yours with --key-env |
error: only https URLs are allowed / error: expected https://host/owner/repo |
Use the repository's https:// link |
error: non-public address |
The link points to a private network address; Nehemvix only reads public hosts |
the repository was not found, or it is private and needs credentials |
Check the link; for a private repository give a token with --git-token-env |
== stopped before spending: the estimate is up to $0.038, above --cap … |
Run again with the --cap it suggests |
== stopped before spending: this model's price is unknown … |
Give --price-in and --price-out |
== stopped before spending: finishing 9 sections may cost up to $0.98, and $1.89 is already spent … |
nehemvix finish with the --cap it suggests (the cap is for the whole job) |
error: unknown --format 'epub' |
Use html, pdf, docx, pptx or drawio |
error: set GIT_TOKEN in the environment |
Export the token variable you named with --git-token-env |
== paused: the provider rejected the credentials … |
Check the key, the model's access and billing, then nehemvix resume |
nehemvix --version shows an older version, or invalid choice: 'doctor' |
An older copy, installed with pip, comes first on your PATH. which -a nehemvix lists every copy; remove the old one with python -m pip uninstall aelsha-nehemvix, using the Python it belongs to (with pyenv, run pyenv rehash afterwards) |
To use Nehemvix in CI, Docker or your docs site, see Integrations.