grav-bar 26.9.1

Fast, zero-dependency, and themed status line for the Google Antigravity CLI. Compatible also with Claude code.
# 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.

| 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 |

![All themes](docs/themes.png)

## 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:

```sh
git config core.hooksPath .githooks
```

## License

[MIT](LICENSE)