man tells you about one command. --help tells you about one invocation. Neither explores a tool you don't already know.
$ mandible docker
A tree of every command, subcommand and flag on the left. The selected one's documentation on the right.
Tip
Try running mandible mandible
Linux and macOS, on x86_64 and arm64. Windows is not supported: the containment above
relies on POSIX process groups, and Windows tools use conventions (/?, PowerShell's
own help system) this project does not speak.
Cargo
# fetch prebuilt binary
cargo binstall mandible# build from source
cargo install mandibleFedora / EPEL (COPR repo)
sudo dnf copr enable as-foss/mandible
sudo dnf install mandibleNix
nix run github:AS-FOSS/mandibleHomebrew (macOS or Linux)
brew install as-foss/mandible/mandibleDebian / Ubuntu (signed apt repo)
sudo curl -fsSL https://as-foss.github.io/mandible-apt/mandible-archive-keyring.gpg \
-o /usr/share/keyrings/mandible-archive-keyring.gpg
sudo tee /etc/apt/sources.list.d/mandible.sources >/dev/null <<'EOF'
Types: deb
URIs: https://as-foss.github.io/mandible-apt
Suites: stable
Components: main
Architectures: amd64 arm64
Signed-By: /usr/share/keyrings/mandible-archive-keyring.gpg
EOF
sudo apt-get update && sudo apt-get install mandibleStandalone binaries, .deb and .rpm packages, each with a .sha256, are attached
to every release.
There is no per-tool logic anywhere in this project. No if tool == "docker", no
vendored catalogue of hand-written definitions. That approach is convenient for a
week and unmaintainable ever after. It is always slightly out of date, and it is
wrong in ways you cannot see from the outside.
The insight it runs on instead: help text isn't written by hand, it's generated, and only a small closed set of generators exists. mandible works out which framework produced a tool's output, then applies that framework's grammar. For example:
| Rust | clap (v2, v3/v4) |
| Go | cobra, urfave/cli, stdlib flag |
| Python | argparse, click, docopt |
| JavaScript | commander, yargs, oclif |
| Java / .NET | picocli, System.CommandLine |
| Others | GNU argp/getopt_long, busybox, Symfony Console, OptionParser/Thor, BSD-terse |
Tip
Open straight at a subcommand: mandible cargo clippy. Subcommands that live
as separate <tool>-<sub> binaries (cargo-clippy, git-lfs) show up too,
marked unverified: they were found on PATH, not in the parent's own help.
That claim is measured, not asserted. cargo xtask coverage runs the pipeline against
every executable on your PATH and scores each one: sources used, framework detected,
nodes, flags, percentage described.
It also carries a structure-sanity column, which exists because a coverage number
alone can be gamed by the very failure it should catch. %described once reported a
tool as fine at 100% while 39 of its 40 subcommands had been fabricated out of wrapped
prose. A metric that improves when the tool gets worse is worse than no metric.
CI gates every change against a fixed tool list, and sweeps the whole PATH
separately for the broad picture.
Coverage is not accuracy, though, and the honest number is lower than a green badge
suggests. Accuracy comes from a human-reviewed audit, where a person checks a randomly
drawn sample of real tools against each tool's own --help text. The sample is
committed to the repo before any verdict is recorded, so it cannot be quietly redrawn
once the results look bad. In the most recent audit, 25 of 43 tools parsed fully
correctly, about 58%. A sample that small leaves real statistical slack, so the true
rate across all tools could sit anywhere between about 43% and 72%. Tools that
mandible itself marks ok do better, at 80% correct with a plausible range of 61%
to 91%.
mandible is useful today and wrong often enough that you should check anything
surprising against the tool's own --help.
Tip
Something parses wrong? Run mandible --report <tool> and paste the output
into an issue. That takes two
minutes and is a complete contribution on its own.
Settings live in ~/.config/mandible/config.toml. The file doesn't need to
exist; everything has a default.
Long preformatted lines (the raw --help view, USAGE synopses) scroll
sideways with ←/→ (or h/l) instead of wrapping, and a dim </>
marker sits beside each line that continues past the pane edge. Set
horizontal_scroll = false to wrap everything instead.
# ~/.config/mandible/config.toml
[ui]
horizontal_scroll = true # the defaultGetting a tool's documentation right is mandible's job, not yours. If
something parses wrong, mandible --report <tool> plus an issue fixes it for
everyone. (Local per-tool corrections do exist for the impatient:
~/.config/mandible/overrides/<tool>.toml.)
| Variable | Effect |
|---|---|
NO_COLOR |
Disable colour. TERM=dumb and piped output do the same |
MANDIBLE_ASCII=1 |
Force the ASCII glyph set, for terminals that mangle Unicode |
MANDIBLE_CONFIG_DIR |
Read config and overrides from a different directory |
MANDIBLE_LOG |
Tracing filter, written to stderr |
? inside mandible lists every binding, and the footer keeps the important ones
on screen: arrows or hjkl to move, / to search, Tab between panes, ←/→
to scroll wide lines sideways, t for the tool's own --help, y to copy the
selected flag, q to quit.
Search has two modes: names matches command names literally; everything
searches flags and descriptions fuzzily, so gco finds checkout. / opens
the first, pressing it again switches to the second.
The packages install shell completions for you. For a hand-built binary,
mandible --completions <shell> prints the script (bash, zsh, fish, and
more); drop it wherever your shell looks for completions. For zsh:
$ mkdir -p ~/.zfunc && mandible --completions zsh > ~/.zfunc/_mandiblethen add fpath=(~/.zfunc $fpath) to ~/.zshrc, above its compinit line.
zsh silently skips completion directories it considers insecure (anything
under /tmp), so keep the file under your home.
The tool argument completes too, to the command names on your PATH:
mandible gi<TAB> suggests git rather than whatever files sit in the
current directory. zsh and fish do this today; bash's script format can't
express it yet.
y gets a spelling as far as the clipboard. To land it on the command line
instead, add the shell integration:
$ eval "$(mandible --shell-init bash)" # or: zsh — in your ~/.bashrc, ~/.zshrcNow type a tool name, press Ctrl-X m, browse, and press Enter: the command
you selected (git commit --amend, say) replaces the line, ready to edit.
Quit with q and the line stays exactly as it was.
The binding is a few lines of shell around mandible --print-selection <tool>,
which browses as usual but makes Enter print the selection instead of
expanding the row (the UI draws on stderr, so stdout carries just that one
line). Bind it to a different key, or wrap it in your own widget, by reading
what --shell-init prints.
$ mandible --doctor gh
framework: cobra (from artifact)
nodes: 29
flags: 2 (100.0% described)--doctor reports which framework mandible identified, which sources
contributed, and how much of the tool it understood. It turns "mandible is
wrong about tool X" into "the cobra grammar mishandles Y", which is a bug
someone can actually fix.
docs/design.md |
Design authority: the source model, the safety policy, and the measurement behind every non-obvious decision |
AGENTS.md |
The invariants table. Every entry names the failure it prevents |
If a tool renders wrong, an issue is the fastest way to tell us. Run
mandible --report <tool> and paste the output into the issue form; it asks
for the rest (your OS, what you expected, a screenshot if you have one). Your
tool's version and its exact help text vanish when you upgrade, and nobody
else can recover them, so the report is a complete contribution on its own.
If you want to go further, audit mandible against the tools on your own machine. Every accuracy figure here comes from one Ubuntu machine on ARM, so whatever you have installed is probably software this project has never seen.
$ git clone https://github.com/AS-FOSS/mandible && cd mandible
$ cargo xtask audit contributeThe command asks for your GitHub login, scans your PATH, draws twenty tools
and opens each one in the normal interface next to its real help text. Press
t to see the raw text, then c, i, w or s for correct, incomplete,
wrong or skip. It saves after every verdict, so you can Ctrl-C and come back
later. When you finish, it writes your verdicts under
audit/submissions/<your-login>/ and prints the commands to commit them and
open the pull request. Merged audits sit under your name in the tree and are
credited in the release notes.
Note
When auditing, verify by hand and by eye only, in the interface itself:
cargo xtask audit contribute opens it for you, and mandible --review <seed> reopens an unfinished draw. mandible does have automated checks
(pty renders of the TUI, and cargo xtask audit emit and review, which
print a tool's raw help text beside the tree as plain text for machines
with no terminal), however none of them can tell you what was missed or
which flags are wrong. That judgement is the whole point of an audit. So:
no AI, no CI, nothing non-manual, and no verdicts formed from the text dump.
CONTRIBUTING.md has the details, plus writing tests and
changing the parser.
