grav-bar
Fast, zero-dependency, themeable status line built in Rust for the Claude Code and Google Antigravity (agy) CLIs.
ash ~/repos/grav-bar ( main ) · Fable 5.1 (1M context) · ctx 4% · 5h ██░░░ 37% (2h15m) · wk ███░░ 62% (2d7h)
Features
- Fast: Pure Rust with zero external dependencies. It completes execution in <1ms.
- Works with both CLIs: Auto-detects whether Claude Code or Antigravity is piping to it and reads each one's payload format.
- Dynamic Resizing: Shortens the model name, path, timers, username, and branch one step at a time until the line fits the terminal width.
- Usage gauges: 5-hour and weekly rate-limit gauges with time-until-reset, plus context-window usage.
- Themes: Seven built-in color themes with truecolor gradients, selectable with
--theme.
Installation
From crates.io
Note: This installs the binary to ~/.cargo/bin/grav-bar.
From Source
Configuration
Claude Code
Add to ~/.claude/settings.json:
Google Antigravity
Add to ~/.gemini/antigravity-cli/settings.json:
(If you built from source, use /Users/YOUR_USER/.local/bin/grav-bar instead.)
Themes
Select a theme with --theme <name> or the GRAV_BAR_THEME environment variable. Run grav-bar --list-themes to print the names. An unknown name falls back to default with a warning on stderr.
| Name | Look |
|---|---|
default |
Sky, lavender, pink, indigo on slate with a blue → violet → pink usage gradient |
classic |
Plain 16-color ANSI (cyan/yellow/magenta/blue) with green/yellow/red thresholds. Use this on terminals without truecolor. |
nord |
Nord palette |
catppuccin-mocha |
Catppuccin Mocha palette (catppuccin also works) |
gruvbox |
Gruvbox dark palette |
dracula |
Dracula palette |
tokyo-night |
Tokyo Night palette |

Options
--theme <name> Color theme (or set GRAV_BAR_THEME). Default: default
--caller <name> Force the payload format: claude | agy (default: auto-detect)
--list-themes Print available theme names and exit
-h, --help Show this help
-V, --version Show version
How It Works
grav-bar reads one JSON payload from stdin each time the host CLI refreshes. It never parses the whole document; it looks up only the keys it needs by string search, scoped to the right parent object so that, for example, context_window.used_percentage is not confused with rate_limits.five_hour.used_percentage.
The caller is detected from keys only Claude Code emits (context_window, rate_limits, transcript_path). Anything else is treated as Antigravity. Override with --caller.
| Purpose | Claude Code | Antigravity |
|---|---|---|
| Directory | workspace.current_dir |
cwd |
| Model | model.display_name |
display_name |
| Context used | context_window.used_percentage |
used_percentage |
| 5-hour window | rate_limits.five_hour (percent used, resets_at epoch) |
quota.{3p,gemini}-5h (fraction remaining, reset_in_seconds) |
| Weekly window | rate_limits.seven_day |
quota.{3p,gemini}-weekly |
| Terminal width | COLUMNS env var |
terminal_width |
| Git branch | git rev-parse --abbrev-ref HEAD |
branch, falling back to git |
Antigravity's per-model quotas are chosen by model name: Claude, GPT, and OSS models read the 3p-* keys, everything else reads gemini-*.
When the line is wider than the terminal it is rebuilt at increasing compaction levels: drop the model's parenthesised suffix, shorten the directory to its basename, drop the reset timers, drop the username, drop the branch.
Contributing
Pull requests are welcome!
Git Hooks
We use a shared pre-commit hook to automatically format and lint the code before each commit. After cloning, run: