Script clika-modelverse
The clika-modelverse executable is built to be driven by scripts, and the contracts below are stable interfaces, not implementation details. A script that branches on them keeps working across releases.
stdout is the payload, stderr is everything else
Every command writes exactly its payload to stdout: generated text, a transcript, the catalog, a fetched path, CSV. Banners, progress bars, timings, warnings and errors all go to stderr. Capturing a result is therefore safe by construction:
MODEL_DIR=$(clika-modelverse fetch meta-llama/Llama-3.2-1B-Instruct)
ANSWER=$(clika-modelverse "$MODEL_DIR" prompt "Two plus two is" --greedy --max-new-tokens 4)
-q mutes stderr down to warnings and errors, -v raises it to debug (including the effective-options report showing which value came from which source), and --no-color strips styling (also honored automatically for non-TTY output, NO_COLOR, and TERM=dumb). The runtime's own [ClikaRT] log lines follow the same rule: the level tag is colored only when stderr is a terminal, NO_COLOR is unset or empty, and TERM is not dumb, so a captured stderr holds no escape bytes. None of these change the payload.
Machine-readable forms exist where the payload is tabular: devices --json and devices --csv print the hardware report as a document instead of the human view.
The exit-code contract
Four values, fixed:
| Exit | Meaning | Example |
|---|---|---|
| 0 | success | the payload is on stdout |
| 1 | runtime failure | download interrupted, weights failed to load |
| 2 | usage error | unknown flag, missing argument, unselected weight options |
| 3 | the model cannot do this here | a verb the family does not provide, an identity-only family, an unsupported variant |
The distinction between 2 and 3 is the useful one: 2 means fix the invocation, 3 means fix the model choice. A retry loop should retry 1 and never 2 or 3.
SRC=openai/whisper-large-v3-turbo # the model this script expects
FILE=meeting.wav # the input it transcribes
if ! clika-modelverse "$SRC" transcribe "$FILE" > out.txt; then
case $? in
2) echo "bad invocation, check the flags" >&2; exit 2 ;;
3) echo "$SRC has no transcribe; pick a speech-to-text model" >&2; exit 3 ;;
*) echo "runtime failure, retrying" >&2 ;;
esac
fi
Options as a file
generate-template writes a JSON file with every root option at its default (null where there is no built-in default); --template loads one, and explicit flags always win over it. This is how a deployment pins its configuration in version control instead of a growing alias:
clika-modelverse generate-template defaults.json
clika-modelverse info "$SRC" --template defaults.json
clika-modelverse fetch "$SRC" --template defaults.json --cache-dir /data/models
A family's own verbs are their own contract; the template governs the root verbs. Secrets stay out of both: the Hugging Face Hub token is HF_TOKEN in the environment, never a flag and never a template key, so neither shell history nor a committed template can leak it.
Completion
clika-modelverse generates its own shell completion:
source <(clika-modelverse completion bash) # zsh and fish work the same way
Completion covers the root verbs and flags; model commands are discovered per source at run time, which completion cannot see, and that is the one place tab-completion ends and <source> --help takes over.