docsv0.5.1

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

OptionDefaultDescription
-y, --yesoffRun the default plan with no questions (ci, scripts). Output is plain lines.
--version <VERSION>this binary's versionRelease tag to fetch the payload from. A leading v is optional. There is no latest. Ignored when URNA_RELEASE_BASE is set.
--forceoffReinstall the payload even when one is present. Affects the payload step only.
--no-payloadoffSkip the embedder payload step.
--no-pythonoffSkip the python env step (bring your own via URNA_PYTHON).
--uninstalloffRemove the payload and the env setup created (never the binary). Cannot be combined with --force, --no-payload, --no-python or --version.
-h, --helpPrint help.

How it works

Setup runs in one of two modes:

  • Interactive, when --yes is 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 --yes or 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:

FactHow it is found
urnathe binary's version and <arch>-<os>
channelread 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
simdthe runtime's SIMD backend
data dirthe install root plus /urna (see paths); "no HOME, set URNA_DATA_DIR" when none resolves
embedderwhether the potion embedder script resolves (the table itself is checked later, by verify)
pythonthe interpreter the embedder would run under, with its version
numpy, tokenizerswhether that interpreter imports both
env tooluv on PATH, else a base Python (python3 or python; on Windows python or py) that can import venv, ensurepip
curlcurl on PATH

Plan

StepTicked by default whenBlocked when
embedder payloadno embedder resolves, or --force; never with --no-payloadno data dir; curl is not on PATH
python envthe resolved interpreter lacks numpy or tokenizers; never with --no-pythonneither uv nor a base Python is on PATH; URNA_PYTHON is set to an interpreter without the packages
verifyalways (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 .venv in the working directory or up to three parents. Run setup from inside another project whose .venv has numpy and tokenizers, 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 pull or sh scripts/fetch_potion.sh.

Payload download

  1. Remove leftovers of an interrupted run at the top level of the install root: files named .urna-payload-* and directories named .urna-setup-*.
  2. Build the URL: ${URNA_RELEASE_BASE}/urna-embedder-payload.tar.gz when URNA_RELEASE_BASE is set (a trailing / is trimmed), else https://github.com/hoffresearch/urna/releases/download/v<version>/urna-embedder-payload.tar.gz.
  3. Fetch <url>.sha256 and take its first token, which must be 64 hex digits.
  4. Stream the payload through curl into <install root>/.urna-payload-<pid>.tar.gz, hashing it on the way.
  5. Compare the SHA-256. On a mismatch, delete the download and stop with exit 11: nothing was installed.
  6. Unpack into <install root>/.urna-setup-<pid>/. Any entry that would land outside that directory (.., an absolute path) aborts the install.
  7. Require urna/forge/embed_query_potion.py in the staged tree, remove the old <install root>/urna/forge and move the new one into place. The venv/ next to it is not touched.
  8. 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 uv on PATH: uv venv --allow-existing --quiet <dir>, then uv 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.dev

A 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.

ScreenWhat it showsKeys
splashversion, target and channel; "press enter to begin" after a momentEnter, Space or Right: begin; q or Esc: quit
scanthe facts above, one by one, with the note that nothing is written until you confirm the plan; moves to the plan on its ownEnter (once the probe finished): skip ahead; q or Esc: quit
planone checkbox per step, blocked steps with their reason; at 90 columns or wider, where each part goesUp or k, Down or j: move; Space or x: toggle; Enter: install; q or Esc: quit
installone row per step with progress, and a scrollable log of every tool lineUp or k, Down or j: scroll the log; End: follow; q and Esc do nothing here
verifythe doctor rows, "urna is ready" or "setup finished with problems", each failure's message, and the next commandsEnter, 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 --uninstall

Removes <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

CodeMeaning
0every planned step succeeded, nothing wanted was blocked, verify passed; also a successful --uninstall
2 to 6the steps succeeded but verify failed with this doctor code
10download failed: the .sha256 could not be fetched or parsed, or the payload download failed
11the payload does not match the release checksum; nothing was installed
12unpack 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
13Python env failed: creating the venv, installing the packages, or the import check
14a step that should run is blocked: no curl, no data dir, no uv and no base Python, or URNA_PYTHON without the packages
130cancelled in interactive mode: Ctrl+C at any screen, or q or Esc before the install starts
1an error outside the steps: the terminal could not be initialized, or --uninstall failed
2also 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 --yes

Refresh the payload only, keeping the Python env as it is:

urna setup --yes --force --no-python

Use your own interpreter instead of a managed venv:

export URNA_PYTHON=/opt/py312/bin/python    # must import numpy and tokenizers
urna setup --yes --no-python

Install the payload from a local directory holding urna-embedder-payload.tar.gz and its .sha256:

URNA_RELEASE_BASE=file:///srv/urna-release urna setup --yes

Fetch the payload of a specific release, for a binary built ahead of its tag:

urna setup --yes --version 0.5.1

Keep a log of a run for a bug report:

urna setup --yes > setup.log

On this page