# 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
```sh
cargo install grav-bar
```
*Note: This installs the binary to `~/.cargo/bin/grav-bar`.*
### From Source
```sh
git clone https://github.com/AABelkhiria/grav-bar.git
cd grav-bar
cargo build --release
cp target/release/grav-bar ~/.local/bin/grav-bar
```
## Configuration
### Claude Code
Add to `~/.claude/settings.json`:
```json
{
"statusLine": {
"type": "command",
"command": "~/.cargo/bin/grav-bar --theme nord"
}
}
```
### Google Antigravity
Add to `~/.gemini/antigravity-cli/settings.json`:
```json
{
"statusLine": {
"type": "custom",
"command": "/Users/YOUR_USER/.cargo/bin/grav-bar --theme nord",
"enabled": true
}
}
```
*(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.
| `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
-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`.
| 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:
```sh
git config core.hooksPath .githooks
```
## License
[MIT](LICENSE)