urna setup
Reference for urna setup, the installer that lays down the offline embedder payload and a Python env, then proves the install with the doctor checks.
urna setup lays down what the binary cannot carry: the offline query embedder payload (the potion table and its Python scripts, about 30 MB) and a Python env with numpy and tokenizers. It then runs the doctor checks and exits with a typed code. It never installs, moves or removes the urna binary; the package manager that installed it owns it.
The subcommand exists only in builds with the default tui feature. cargo install urna --no-default-features has no setup.
Usage
urna setup [OPTIONS]Options
| Option | Default | Description |
|---|---|---|
-y, --yes | off | Run the default plan with no questions (ci, scripts). Output is plain lines. |
--version <VERSION> | this binary's version | Release tag to fetch the payload from. A leading v is optional. There is no latest. Ignored when URNA_RELEASE_BASE is set. |
--force | off | Reinstall the payload even when one is present. Affects the payload step only. |
--no-payload | off | Skip the embedder payload step. |
--no-python | off | Skip the python env step (bring your own via URNA_PYTHON). |
--uninstall | off | Remove the payload and the env setup created (never the binary). Cannot be combined with --force, --no-payload, --no-python or --version. |
-h, --help | Print help. |
How it works
Setup runs in one of two modes:
- Interactive, when
--yesis not given and both stdin and stdout are terminals. It draws inline in the terminal (the screen stays in the scrollback when it ends): a splash, then four stages, scan, plan, install and verify. - Plain, with
--yesor without a terminal on both ends (CI, a pipe, a redirect, an npm postinstall). It runs the default plan and prints one line per event.
Both modes run the same worker. The steps run in order; a failed step does not stop the next one, and verify always runs, so the run ends on the real state of the install.
Scan
Setup first probes the machine, read-only:
| Fact | How it is found |
|---|---|
urna | the binary's version and <arch>-<os> |
channel | read off the binary's resolved path: /Cellar/, /homebrew/ or /linuxbrew/ is homebrew; /node_modules/ is npm (for every Node package manager); /.cargo/bin/ is cargo; /target/debug/ or /target/release/ is dev build; /.local/bin/ is install script; anything else is manual |
simd | the runtime's SIMD backend |
data dir | the install root plus /urna (see paths); "no HOME, set URNA_DATA_DIR" when none resolves |
embedder | whether the potion embedder script resolves (the table itself is checked later, by verify) |
python | the interpreter the embedder would run under, with its version |
numpy, tokenizers | whether that interpreter imports both |
env tool | uv on PATH, else a base Python (python3 or python; on Windows python or py) that can import venv, ensurepip |
curl | curl on PATH |
Plan
| Step | Ticked by default when | Blocked when |
|---|---|---|
| embedder payload | no embedder resolves, or --force; never with --no-payload | no data dir; curl is not on PATH |
| python env | the resolved interpreter lacks numpy or tokenizers; never with --no-python | neither uv nor a base Python is on PATH; URNA_PYTHON is set to an interpreter without the packages |
| verify | always (cannot be unticked) | never |
A step runs when it is ticked and not blocked. If any ticked step is blocked, the run's exit code starts at 14. In interactive mode you can tick or untick the payload and Python steps, except blocked ones.
Two cases where the plan skips a step you might expect:
- The interpreter lookup includes the nearest
.venvin the working directory or up to three parents. Run setup from inside another project whose.venvhasnumpyandtokenizers, and it plans no managed venv. Run it from a neutral directory, or build the venv anyway by ticking it. - In a repo checkout, the checkout's embedder counts as present, so the payload step starts unticked even when the checkout's potion table is a git-lfs pointer. Setup cannot fix that table: run
git lfs pullorsh scripts/fetch_potion.sh.
Payload download
- Remove leftovers of an interrupted run at the top level of the install root: files named
.urna-payload-*and directories named.urna-setup-*. - Build the URL:
${URNA_RELEASE_BASE}/urna-embedder-payload.tar.gzwhenURNA_RELEASE_BASEis set (a trailing/is trimmed), elsehttps://github.com/hoffresearch/urna/releases/download/v<version>/urna-embedder-payload.tar.gz. - Fetch
<url>.sha256and take its first token, which must be 64 hex digits. - Stream the payload through
curlinto<install root>/.urna-payload-<pid>.tar.gz, hashing it on the way. - Compare the SHA-256. On a mismatch, delete the download and stop with exit
11: nothing was installed. - Unpack into
<install root>/.urna-setup-<pid>/. Any entry that would land outside that directory (.., an absolute path) aborts the install. - Require
urna/forge/embed_query_potion.pyin the staged tree, remove the old<install root>/urna/forgeand move the new one into place. Thevenv/next to it is not touched. - Delete the download and the staging directory.
The previous payload survives every failure up to step 7.
curl runs as curl --silent --show-error --fail --location --proto =https,file --proto-redir =https --retry 2 --connect-timeout 20. So only https:// and file:// URLs work, a redirect can only go to HTTPS, and there is no overall time limit: a server that stalls mid-transfer can hang setup. A 404 on a GitHub release URL is reported as "release vX.Y.Z has no urna-embedder-payload.tar.gz on github (404): this build is ahead of its tag; pass --version with a published one".
Python env
Setup builds a venv at <install root>/urna/venv (interpreter bin/python, or Scripts\python.exe on Windows):
- With
uvonPATH:uv venv --allow-existing --quiet <dir>, thenuv pip install --python <dir>/bin/python numpy>=1.26 tokenizers>=0.20. - Otherwise with the base Python:
<python> -m venv <dir>(only when the venv interpreter does not exist yet), then<venv python> -m pip install --disable-pip-version-check --progress-bar off numpy>=1.26 tokenizers>=0.20.
It then runs import numpy, tokenizers in the new env. Every line the tools print goes to the log.
This step downloads packages from the package index pip or uv is configured with, and uv may download a Python when the machine has none. It is the one part of setup that does not go through curl. For a machine without an index, see air-gapped install.
Setup checks no Python version. The pip wheel's floor is Python 3.12.
Verify
Verify runs the doctor checks in process. It passes with "every check passes, offline", or fails with the first failing check's code (2 to 6) and message.
Output
In plain mode everything goes to stdout, colored only when stdout is a terminal and neither NO_COLOR nor URNA_COLOR=none is set. The shape of a run (abridged; paths and versions vary by machine):
urna setup 0.5.1 aarch64-macos
urna 0.5.1 · aarch64-macos
channel homebrew · /opt/homebrew/Cellar/urna/0.5.1/bin/urna
simd neon
data dir ~/.local/share/urna
embedder missing, setup downloads it
python Python 3.12.4 · python3
numpy, tokenizers missing, setup builds a venv
env tool uv · ~/.local/bin/uv
curl /usr/bin/curl
==> embedder payload
source https://github.com/hoffresearch/urna/releases/download/v0.5.1/urna-embedder-payload.tar.gz
checksum
downloading
10% 2.8 / 28.4 MB
...
100% 28.4 / 28.4 MB
verifying sha256
sha256 ok <64 hex digits>
unpacking
...
ok embedder payload: 28.4 MB · sha256 <12 hex digits>… · ~/.local/share/urna/forge
==> python env
building with uv
$ <uv> venv --allow-existing --quiet <venv>
...
ok python env: ~/.local/share/urna/venv/bin/python · numpy <version> · tokenizers <version>
==> verify
running the doctor checks
ok version: urna 0.5.1, format v1
...
ok verify: every check passes, offline
urna setup: ready
try: urna tui · urna build --spec corpus.toml · https://urna.devA step that does not run prints skip <step>: <reason> before the first ==>. A failed step prints fail(<code>) <step>: <message>, and the last line is urna setup: failed.
The suggested urna build does not work on an installed binary
The last line of a successful run, and the interactive success screen, suggest urna build --spec corpus.toml. The build tool is not in any release artifact, so an installed binary fails with "urna_forge.py not found". urna build runs from a repo checkout. See known limits.
Interactive screens
The inline viewport is the terminal height minus two rows, kept between 12 and 22 rows. Below 30 by 6 it shows "urna setup: terminal too small". The three-row header needs a viewport of at least 20 rows; smaller viewports get a one-row header.
| Screen | What it shows | Keys |
|---|---|---|
| splash | version, target and channel; "press enter to begin" after a moment | Enter, Space or Right: begin; q or Esc: quit |
| scan | the facts above, one by one, with the note that nothing is written until you confirm the plan; moves to the plan on its own | Enter (once the probe finished): skip ahead; q or Esc: quit |
| plan | one checkbox per step, blocked steps with their reason; at 90 columns or wider, where each part goes | Up or k, Down or j: move; Space or x: toggle; Enter: install; q or Esc: quit |
| install | one row per step with progress, and a scrollable log of every tool line | Up or k, Down or j: scroll the log; End: follow; q and Esc do nothing here |
| verify | the doctor rows, "urna is ready" or "setup finished with problems", each failure's message, and the next commands | Enter, q or Esc: exit with the run's code |
Ctrl+C exits at any screen with code 130 and prints urna setup: cancelled. Child processes (curl, pip, uv) are not stopped explicitly; a partial download is removed by the next run.
The plan screen's "where it goes" panel always names the GitHub release of the binary's version as the source, even when URNA_RELEASE_BASE or --version point elsewhere. The URL actually used is logged as source <url>.
Uninstall
urna setup --uninstallRemoves <install root>/urna/forge and <install root>/urna/venv, printing removed <path> for each one that exists, then urna setup: uninstalled the payload and the env; the binary stays with its package manager. Anything else under <install root>/urna/ stays. The install root comes from the current environment, so a different URNA_DATA_DIR, XDG_DATA_HOME or LOCALAPPDATA than at install time targets a different directory. Without any data directory it fails with "no data dir (set URNA_DATA_DIR)" and exit 1. Per-channel uninstall is in installation.
Exit codes
| Code | Meaning |
|---|---|
0 | every planned step succeeded, nothing wanted was blocked, verify passed; also a successful --uninstall |
2 to 6 | the steps succeeded but verify failed with this doctor code |
10 | download failed: the .sha256 could not be fetched or parsed, or the payload download failed |
11 | the payload does not match the release checksum; nothing was installed |
12 | unpack failed: the install root cannot be created, the archive is unreadable, an entry escapes the staging directory, the payload lacks the embedder script, or the swap failed |
13 | Python env failed: creating the venv, installing the packages, or the import check |
14 | a step that should run is blocked: no curl, no data dir, no uv and no base Python, or URNA_PYTHON without the packages |
130 | cancelled in interactive mode: Ctrl+C at any screen, or q or Esc before the install starts |
1 | an error outside the steps: the terminal could not be initialized, or --uninstall failed |
2 | also a usage error, such as an unknown flag or --uninstall --force |
The first non-zero code wins: a blocked step's 14 beats a later failure, and an earlier step's failure beats verify's code.
Examples
Install everything, no questions:
urna setup --yesRefresh the payload only, keeping the Python env as it is:
urna setup --yes --force --no-pythonUse your own interpreter instead of a managed venv:
export URNA_PYTHON=/opt/py312/bin/python # must import numpy and tokenizers
urna setup --yes --no-pythonInstall the payload from a local directory holding urna-embedder-payload.tar.gz and its .sha256:
URNA_RELEASE_BASE=file:///srv/urna-release urna setup --yesFetch the payload of a specific release, for a binary built ahead of its tag:
urna setup --yes --version 0.5.1Keep a log of a run for a bug report:
urna setup --yes > setup.logurna doctor
Reference for urna doctor, the offline install check that tests the Python env, the potion embedder and one real embed, and exits with a typed code.
urna tui
Reference for urna tui, the full-screen terminal explorer that opens a .urna file, shows its sections, asks it questions and runs the install checks.