Skip to content

Latest commit

 

History

79 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cli-status-border

An animated status bar pinned to the top row of the terminal: a thin true-24-bit-color line spans the full width, with a wide band of light sliding smoothly across it — a flat full-brightness core with straight linear ramps fading to near-black on either side, at a constant hue — while your process is running. Call succeed()/fail() to stop the animation and hold solid green/red.

Uses a terminal scroll region (DECSTBM) to reserve row 1 for the bar, so your program's own console.log output keeps scrolling normally underneath it without any conflict.

Terminal compatibility

Works cleanly in traditional terminal emulators: iTerm2, Terminal.app, WezTerm, Alacritty, Kitty, and similar.

Warp is not supported. Warp's block-based UI doesn't render a classic scroll region the way this library needs — the bar can appear at less than full width with stray [/] characters at its edges (Warp's own block-boundary decorations, not bytes this library emits). start() prints a one-time warning when it detects Warp (TERM_PROGRAM=WarpTerminal); there's no escape-sequence fix for it, so use a traditional terminal instead.

Install

npm install cli-status-border

Usage

import { StatusBorder } from 'cli-status-border';

const border = new StatusBorder({ color: 'cyan' });

border.start();
console.log('doing some work...');
await doSomeWork();
border.succeed(); // stops the pulse, holds a solid green bar
// or: border.fail();  // holds a solid red bar
border.stop(); // give the terminal back whenever you're ready

You can also change the color while it's animating:

border.setColor('#ff8800');

To cycle a long-lived bar between "busy" and "settled" repeatedly without ever calling stop() in between, use pulse() — the counterpart to succeed()/fail() that resumes the animation:

border.pulse('yellow'); // resume animating in a new color

If you want the bar to disappear between busy periods without releasing the reserved row (what the shell-wide daemon does between commands), use hide() instead of stop(). Unlike stop()/start(), which is meant to run once per terminal session, hide() only blanks the bar's own row and never touches the rest of the screen — safe to call repeatedly without disturbing whatever else has been printed:

border.start({ silent: true }); // reserve the row once, up front, without drawing yet
// ...later, per busy period...
border.pulse('yellow');
// ...later, once settled...
border.settle('green');
border.hide(); // blank the row; pulse()/settle() show it again

Shell-wide mode (any command, not just Node.js)

Want the bar to react to every command run in a terminal — Python, git, bash, anything — with zero code changes? One-time setup:

npm install -g cli-status-border
cli-status-border

That opens a create-vite-style wizard: pick your color with the arrow keys, hit Enter, done — it saves the choice to ~/.cli-status-border.json and installs the shell integration into your ~/.zshrc / ~/.bashrc automatically. Open a new terminal and the bar reacts to every command you run: an idle terminal shows nothing — the bar appears the moment a command starts (pulsing in your chosen color), holds solid green or red for a couple seconds once it finishes, then disappears again.

Change the color anytime (running terminals update live, no restart):

cli-status-border color

Under the hood: each terminal gets its own little daemon that draws the full-width bar, and preexec/precmd hooks (zsh) or the DEBUG trap + PROMPT_COMMAND (bash) write busy/ok/error into a per-terminal state file the daemon watches. Its writes are synchronous so a complete frame reaches the terminal together instead of interleaving with foreground-command output. Colors can also be overridden per-terminal with CLI_STATUS_BORDER_BUSY_COLOR / _OK_COLOR / _ERROR_COLOR env vars, and how long the solid result holds before hiding with CLI_STATUS_BORDER_HOLD_MS (default 2000).

Options

new StatusBorder({
  color: 'green',   // color name (red, green, yellow, blue, magenta, cyan, white, gray) or a hex string like "#ff8800"
  pulseWidth: 10,   // length of the moving pulse's glow, in columns (default: the full terminal width)
  dimBrightness: 0.04,   // brightness (0-1) of the dimmest, unlit part of the line (default fades to near-black)
  plateauFraction: 0.33, // fraction of the glow that's a flat, full-intensity core
  bloom: 0,         // how hard the core blooms toward white (0 = constant hue, 1 = white-hot);
                    // off by default — the white shift reads as per-cell banding at the core
  gradientSteps: 96, // color steps in the pulse (lower values make each frame smaller)
  taper: false,     // opt-in: vary the line's height by intensity too (thin edges, fat middle) —
                    // off by default because the per-column height steps (▁▂▃▄) read as boxes
  char: '▔',        // the character the line is drawn with (default: upper one-eighth block —
                    // a thin line hugging the top edge of the row)
  fps: 40,          // redraw rate
  speed: 6,         // columns the pulse travels per frame
  stream: process.stdout,
});

Behavior notes

  • The bar stays up for exactly as long as your process is: it appears on start() and disappears on stop() — nothing releases it automatically.
  • succeed()/fail() stop the pulse animation and hold a solid color, but don't release the bar themselves; call stop() when you're ready to give the terminal back.
  • If your process exits (normally, via Ctrl+C, or the terminal closing) without calling stop(), a safety net still restores the terminal.
  • No-ops safely when stdout isn't an interactive TTY (piped output, CI logs, etc.) — safe to leave enabled unconditionally in any CLI tool.

Pick a color interactively

Installing the package also gives you a small CLI to preview every color before picking one in code:

npx cli-status-border

Use ↑/↓ to move, Enter to preview a color live in your terminal, Ctrl+C to quit. It prints the exact snippet to use once you've decided.

Try it

git clone https://github.com/shxwat/cli-status-border
cd cli-status-border
npm install && npm run build
node examples/demo.js magenta
node examples/long-demo.js green
node bin/cli.js   # interactive color picker
node bin/daemon.js &   # shell-wide daemon (see "Shell-wide mode" above)

License

MIT

About

A reusable animated status border for CLI tools — a colored bar pinned to the top of the terminal that pulses while a task runs. Any color you want.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages