Small terminal utilities shared across the workspace.
- Domain-neutral progress primitives that can be reused by multiple binaries.
- Structured APIs (
Progress,ProgressOptions,ProgressEnabled) that callers can compose. - Behavior that can be verified with deterministic unit/integration tests.
- Product-specific progress copy, emoji/prefix style, and section wording.
- CLI-specific policy decisions about when progress should appear for a command.
- Exit-code mapping and command-level error/warning text.
nils-term provides a minimal, RAII-friendly progress abstraction that is safe for
machine-readable stdout output:
- progress is drawn to stderr by default
- with
ProgressEnabled::Auto(default), progress is enabled only when stderr is a TTY
use nils_term::progress::{Progress, ProgressOptions};
let total = 3_u64;
let progress = Progress::new(total, ProgressOptions::default().with_prefix("work "));
for i in 0..total {
progress.set_message(format!("item {i}"));
progress.inc(1);
}
progress.finish();use nils_term::progress::{Progress, ProgressFinish, ProgressOptions};
let spinner = Progress::spinner(
ProgressOptions::default()
.with_prefix("fetch ")
.with_finish(ProgressFinish::Clear),
);
spinner.set_message("loading");
spinner.tick();
spinner.finish_and_clear();Prefer accepting a Progress (or ProgressOptions) from the caller instead of reading env vars
inside library code. This keeps libraries deterministic and lets binaries decide whether to show
progress (e.g. interactive vs CI).
When migrating crate-local progress code into nils-term:
- Add/keep characterization tests before moving behavior.
- Keep progress rendering to
stderrso machine-readablestdoutremains stable. - Keep CLI-local adapters for command wording and error/exit semantics.
- Re-run command-contract tests for TTY, non-TTY, JSON, and
NO_COLORflows.