Skip to main content

Script clikart-cli

The clikart-cli 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=$(clikart-cli fetch Qwen/Qwen2.5-0.5B-Instruct)
ANSWER=$(clikart-cli "$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, check --csv prints the fit verdict table (one row per device, every term of the law a column) as CSV, list --json prints the registry as one document (per family: the vendor, the Hugging Face pipeline tags it serves, the modalities, the served and refused model types and GGUF architectures, the advertised verbs, whether it is runnable), and info --json / info --csv print the supported-models document, or its table as CSV, for one source (a one-entry document), several sources or @FILE (one source per line): per model the family, the resolved commit, the parameter count and where it was read from, the license, the gate, and one row per weight variant with the files a fetch lands and their sizes, which a catalog generated from the registry reads. The grammar is clikart-cli info <source... | @FILE> [--weights SEL] [--json | --csv] [--schema] [--dry]: one source with no form flag prints the human description, --schema prints the document's JSON Schema and needs no source, and a source the hub refuses is a warning on stderr while the document carries the rest and the exit code is 1.

The exit-code contract​

Four values, fixed:

ExitMeaningExample
0successthe payload is on stdout
1runtime failuredownload interrupted, weights failed to load
2usage errorunknown flag, missing argument, unselected weight options
3the model cannot do this herea 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 ! clikart-cli "$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:

clikart-cli generate-template defaults.json
clikart-cli info "$SRC" --template defaults.json
clikart-cli 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 comes from HF_TOKEN in the environment or from the token a Hub login stored, never a flag and never a template key, so neither shell history nor a committed template can leak it.

Completion​

clikart-cli generates its own shell completion:

source <(clikart-cli 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.