The console: reference¶
hammunition console is the full-screen terminal front end of the engine. This page is its reference: how it works, what it
never does, its keys and its screens. The walkthrough from a fresh install is The console.
It is part of the engine: the same release and the same version, started with hammunition console. It has no install logic,
no package names and no catalog parser of its own; it asks the engine, through the engine's --json documents
(D-059), and runs the engine's own commands. Whether it works well over SSH or on a
Raspberry Pi has not been measured.
What it is¶
Eight screens: Home, Install, Station, Secrets, Repeaters, Logs, Update and Help. Which CLI verbs they cover, and which have no screen yet, is counted in Console coverage. Every action is a command you could type yourself, and the console
shows it before it runs. Hardware setup is one first-run step on Home (hammunition hardware apply, in a pane, with the
engine's own prompts); everything else about hardware, and maps, is left to the CLI and to
hammunition-tray for now.
Requirements¶
- Hammunition itself. The console is a subcommand, so there is nothing else to install except its one dependency,
urwid 2.6 or later:
sudo apt install python3-urwidon the Debian family (Debian 13 and Parrot carry 2.6.16, Ubuntu 24.04 2.6.10, Ubuntu 26.04 and Kali 3.0.4), orpip install 'hammunition[console]'inside a virtualenv, which does not see the archive's module../bootstrap.shinstalls it into the engine's virtualenv for you. - Python 3.11 or later.
- A terminal of at least 80x24. It refuses to start without a terminal, with
TERM=dumb, or as root, and without urwid it prints one line naming the install command and exits 2.
hammunition console --help lists the keys and the exit codes; hammunition console --version prints the engine's version,
because there is no second one.
How it works¶
Three channels, each with one job.
- Reads run
hammunition <verb> --jsonin a worker thread and parse the one document it prints. The console reads only the verbs listed in what it reads, refuses a document whoseschemait does not know, and shows the engine's version from the first document'senginefield. It never compares it with anything: the console and the engine are one release. - Writes run the real
hammunitioncommand inside a terminal pane. The child owns the tty: sudo's password prompt, the group choice and any consent prompt reach the engine untouched, typed by you. The console sees only the exit code, then reads again. - Its own config,
~/.config/hammunition-console/config.toml: the last screen, the colour theme, whether you dismissed the first-run checklist. Nothing else. (A crash writescrash.logbeside it with the exception type and its frames, never a message.)
The plan always comes first: choosing a profile shows the engine's own dry run (--dry-run), grouped as the engine groups it,
and nothing runs until you press R on it.
The engine it runs is the one that started it: the console launches python -m hammunition with the interpreter it is itself
running under, never whatever hammunition happens to resolve to on PATH, so a checkout's virtualenv, the
bootstrap-linked ~/.local/bin/hammunition and a packaged install each drive their own engine.
What it never does¶
- It never answers a consent prompt for you: you type yes into the engine's own prompt, in the pane.
- It never runs anything but the engine's own commands (and the apt upgrade the engine's update report offers).
- It never writes a secret anywhere: one you enter lives in its memory for the engine commands it starts and is cleared when you quit.
- It never stores your callsign, grid square or any station value; the engine's station file is the only copy.
- It never fetches anything from the network itself; the engine does, and it asks GitHub, git hosts and PyPI only when you press u on Update.
Also: it never passes the engine's assume-yes flag, never sets a scripted-consent environment variable and removes any you
exported from the environment of everything it starts, never runs a doctor fix (it shows the engine's fix text and leaves the
command to you), and never runs as root. The header says only "station: set" or "not set", and the Station screen hides
values until you ask.
Keys¶
| Keys | Meaning |
|---|---|
1-7 |
open the screen with that number (Home) |
Enter |
open the selected row |
b / Esc |
go back; changes nothing (in a text prompt only Esc: b is typed) |
? |
help |
q |
quit |
r |
refresh this screen |
R |
run the planned command in a terminal pane (plan and confirm screens) |
Tab |
switch between profiles and single units (Install) |
U |
plan an uninstall of the selected profile (Install) |
i |
the selected profile's documentation (Install) |
v |
reveal or hide station values (Station) |
c |
clear the selected value, where the engine can (Station) |
g |
where to get the selected secret (Secrets) |
d |
name a Doppler project and config for the selected secret (Secrets) |
e |
enter the selected secret for this session only, hidden (Secrets) |
x |
forget the session value of the selected secret (Secrets) |
f |
run the command the selected secret unlocks (Secrets) |
f |
fetch RepeaterBook by state (Repeaters) |
i |
import your own repeater export (Repeaters) |
a |
choose the active areas (Repeaters) |
x |
remove the selected layer (Repeaters) |
l |
look repeaters up near a place, by band and mode (Repeaters) |
u |
also ask upstream whether the catalog's pins are current (Update) |
A |
run the apt upgrade the report offers (Update) |
B |
plan the rebuilds the report offers (Update) |
s |
skip the selected first-run step (Home) |
D |
dismiss the first-run checklist (Home) |
Screens¶
- Home: the engine's health check, whether the station is set, the last run, units behind their pin, and a first-run checklist (set the station, apply the hardware rules, pick a profile, install it).
- Install: profiles, and with
Tabsingle units; the plan; the run. - Station: the saved values, changed by running the engine's own
station set. - Secrets: the keys the engine can use for downloads that need one (RepeaterBook's token first), where each would come
from (the environment, Doppler or nowhere) and never its value.
gsays where to get one,dnames a Doppler project and config throughstation set,ekeeps a value for this console session only, andfruns the command it unlocks. - Repeaters: the repeater layers on this machine grouped by area (
maps repeaters list --json), the areas and which are active (maps areas --json), and each source's credit exactly as the engine words it.ffetches RepeaterBook by state (and optionally one county),iimports your own export from a file,achooses the active areas with the current set filled in (allandnonestand alone),xremoves the selected layer after showing the command, andllooks repeaters up by place, distance, band and mode into a table of callsign, output, offset, tone, mode, distance and bearing.ffirst asks the engine whetherREPEATERBOOKcan be supplied and opens Secrets with the reason when it cannot; when therepeaterbook-clientunit is not installed it offers the install (the engine's plan, then a pane) and runs the fetch after it succeeds. Choosing areas deletes nothing. The station's own position is used for distances and never printed. - Logs: each run the engine recorded, newest first; a run in progress is followed live.
- Update: installed against the catalog;
ualso asks upstream. - Help: keys, what the console never does, and what each profile is for.
Status¶
Built and tested; not yet run on the field laptop, the target it was built for. What has run: the test suite (unit tests against
fixtures recorded from the engine, a fake hammunition that asks for yes on a real pseudo-terminal, and the console driven
end to end in one), inside the engine's own suite, with urwid 4.x on Python 3.13. The recorded fixtures date from the console's
first release; the earlier CI matrix named urwid 2.6.10, 2.6.16 and 3.0.4 and the Debian 13 and Ubuntu 24.04 archives' own
python3-urwid, and those legs are not yet part of the engine's CI.
What has not been run: the bench run on the field laptop; a real hammunition install through the pane on a real target;
urwid's urwid.Terminal against a real engine install on any machine; Raspberry Pi OS, Pop!_OS and Mint, which are inferred
from their bases. A claim about hardware belongs here only after it has run there.
Development¶
The package is src/hammunition/console/ and its tests are tests/console/, run by the engine's own pytest. The fixtures
are documents the engine printed, kept in tests/console/fixtures/; they are recorded by
tests/console/capture_fixtures.py, which refuses to run unless the HOME the engine would see is a temporary directory
it created itself, outside every real account's home, with the owner variables removed (a capture once overwrote a real
station file through a HOME override). Run it only in a container or a throwaway VM, never on a machine whose station is set.
Review every new fixture by eye before committing: the identifier scan is a net, not a guarantee.