Progress indication for long operations
Why it matters
A CLI that sits silent for ten seconds during a deploy looks frozen. Users hit Ctrl+C, corrupt state, and open a support ticket. Progress indicators on stderr — spinners, counters, bars — tell the user the tool is alive without polluting stdout for scripts. Writing spinners to stdout is the opposite failure: mytool deploy | tee log captures terminal control sequences into the log file, and every subsequent cat log flickers the terminal.
Severity rationale
Low because missing progress indication is a UX annoyance but does not cause data loss or failed operations.
Remediation
Wrap operations over two seconds (network calls, installs, file scans) with a spinner or progress bar routed to stderr, and suppress when !process.stderr.isTTY. In src/cli/commands/deploy.ts:
import ora from 'ora'
const spinner = ora({ text: 'Deploying...', stream: process.stderr }).start()
try { await deploy(); spinner.succeed('Deployed') }
catch (e) { spinner.fail('Failed'); throw e }
Detection
-
ID:
progress-indication -
Severity:
low -
What to look for: Enumerate every long-running operation in the CLI (network calls, file processing, installations). For each, identify operations that may take more than 1-2 seconds (network requests, file processing, build steps). Check that these operations show progress feedback — a spinner (ora, cli-spinners, tqdm), a progress bar, or periodic status messages. Verify that progress output goes to stderr (not stdout). Check that progress indicators are suppressed when stdout is not a TTY.
-
Pass criteria: Long-running operations provide visible progress feedback. Progress output goes to stderr. Progress is suppressed or simplified when not running in a TTY — 100% of operations taking over 2 seconds must show progress feedback. Report: "X long-running operations found, all Y show progress indication."
-
Fail criteria: Long-running operations produce no output until completion (the user sees a hanging terminal), or progress output goes to stdout (corrupts piped data).
-
Skip (N/A) when: All commands complete in under 1-2 seconds (no network calls, no large file processing). All checks skip when no CLI entry point is detected.
-
Detail on fail:
"'deploy' command makes 5 API calls with no progress indication — terminal appears frozen for 10+ seconds"or"Spinner from ora writes to stdout by default — will corrupt piped output" -
Remediation: Users need feedback that the CLI is working, not frozen:
// Node.js — ora spinner on stderr import ora from 'ora' const spinner = ora({ text: 'Deploying...', stream: process.stderr }).start() try { await deploy() spinner.succeed('Deployed successfully') } catch (err) { spinner.fail('Deployment failed') throw err }# Python — tqdm or click.progressbar to stderr import click with click.progressbar(files, label='Processing', file=sys.stderr) as bar: for f in bar: process_file(f)
Taxons
History
- 2026-04-18·v1.0.0·Initial import from cli-quality·automated