Skip to content

Rfluid/aura

Repository files navigation

Aura

Aura

Agent Usage Reporter & Analyzer
Know exactly what your AI agents are spending.


Aura is a lightweight Rust system-tray indicator — sits next to wifi and volume — that gives you instant visibility into AI agent usage: tokens consumed, subscription quota windows, estimated costs, and custom optimizer metrics via a plugin system. Click the icon, see your usage, click again to dismiss.

Contents

Screenshots

Aura tray icon sitting in the KDE Plasma system tray, between the wifi and volume icons
The Aura indicator lives next to wifi / volume — left-click to open.

Aura modal open on the Quota tab: Claude max subscription, Current session 6% used, Current week (all models) 69% used, Current week (Sonnet only) 8% used, each with a progress bar and a 'Resets …' timestamp
Quota tab — live subscription windows from Claude's API.

Aura modal on the Summary tab showing total tokens, sessions, longest session, active days, peak hour, current streak, longest streak
Summary tab — at-a-glance usage stats for the selected period.

Aura modal on the Models tab showing per-model token breakdowns with model names and percentages
Models tab — which models actually ate your tokens.

Top of the Aura modal showing agent profile pills: Peh (Claude), Personal, Codex, Gemini, with the active profile highlighted
One click to switch agent profiles — last selection is persisted.

Right-click context menu on the Aura tray icon with two items: Show Aura, Quit Aura
Right-click for explicit Show / Quit.

Aura modal on the Plugins tab showing the RTK Gains plugin panel with tokens-saved figures
RTK Gains plugin tab — third-party metrics rendered inline.

Why Aura?

Modern development workflows run on AI agents. But usage is invisible until the bill arrives. Aura surfaces that data where you already live — your system tray — without switching context, opening a browser, or running a CLI command.

Features

  • Multi-agent support — Claude Code, Codex, and Gemini out of the box; custom command agents on the roadmap.
  • Agent profiles — configure multiple instances of the same agent (e.g. personal vs. enterprise workspaces) and toggle between them; last selection is persisted across sessions.
  • Plugin system — extend Aura with custom metrics panels; anyone can author a plugin. First-party plugins (incl. RTK Gains for RTK token-savings) are installed separately.
  • Single-click activation — left-click the tray icon to open / close the modal; right-click for Show / Quit.
  • Tray-native — uses ksni on Linux for direct StatusNotifierItem (Plasma / GNOME / sway / etc.) and tray-icon on macOS / Windows for AppKit / Win32 menu-bar integration.

Plugins

Plugins are stand-alone executables that publish JSON panels into the modal. None ship with the core install — Aura itself stays minimal. Plugins are installed separately, either by aura plugin add or by dropping a binary into the user plugins dir (~/.config/aura/plugins/ on Linux).

First-party plugins (built from this repo's plugins/ directory):

Plugin Description
RTK Gains Shows tokens saved by the Rust Token Killer (RTK) optimizer — how much you spent vs. how much you would have spent
Hello (reference only) Minimal example showing the JSON contract for plugin authors

Each plugin's README explains how to build and install it. The aura plugin CLI wraps the common workflows:

aura plugin add ./target/release/aura-plugin-rtk    # install a built plugin
aura plugin list                                     # see what's wired up
aura plugin remove "RTK Gains"                       # uninstall by display name
aura plugin run "RTK Gains" --period 7d              # debug-print panel JSON

Anything in ~/.config/aura/plugins/ is auto-discovered at modal open — no config.toml edit required. To pin the order of the pill row, set [display] plugin_order = ["Hello", "RTK Gains"] in config.toml (see docs/configuration.md). See docs/plugin-authoring.md for the full wire contract and authoring checklist.

CLI

Running aura with no arguments launches the tray; subcommands run headless so they can be scripted. Highlights:

aura doctor                              # paths + agent detection + plugin discovery
aura usage --period 7d --format json     # token snapshot for the active profile
aura quota --format json                 # subscription rate-limit windows
aura state set-profile "Codex"           # switch the active profile from the shell
aura completions zsh > ~/.zfunc/_aura    # shell completions

Every read command takes --format text|json. The legacy spelling aura setup-config still works (hidden alias for aura config setup). See docs/cli.md for the full reference.

Configuration

Aura is configured via a single TOML file at the OS-standard config location:

Platform Config path
Linux ~/.config/aura/config.toml
macOS ~/Library/Application Support/aura/config.toml
Windows %APPDATA%\aura\config.toml

Define as many profiles as you need:

[[agents]]
name = "Claude Code (Personal)"
kind = "claude-code"
config_path = "~/.claude"

[[agents]]
name = "Claude Code (Enterprise)"
kind = "claude-code"
config_path = "~/.claude-enterprise"

[[agents]]
name = "Codex"
kind = "codex"

[[agents]]
name = "Gemini"
kind = "gemini"

# Optional display tweaks. All keys are optional; defaults shown.
[display]
default_period         = "today"      # "today" | "this_month" | "all_time"
anchor                 = "auto"       # "auto" | "top" | "bottom" | "left" | "right"
dismiss_on_focus_loss  = true         # set false to make the modal sticky
show_in_app_switcher   = false        # show Aura in Cmd+Tab / Alt+Tab / WM switcher
# plugin_order         = ["Hello", "RTK Gains"]

config.toml is hot-reloaded — left-clicking the tray icon and the modal's refresh button both re-read the file, so edits take effect without restarting Aura. See docs/configuration.md for the full schema.

Themes

Aura's color tokens are user-customizable via a sibling file:

Platform Theme path
Linux ~/.config/aura/theme.toml
macOS ~/Library/Application Support/aura/theme.toml
Windows %APPDATA%\aura\theme.toml

Every key is optional — anything you don't set falls back to the built-in default. Click Themes in the more menu (•••) and Aura will create the file seeded with the current defaults, then open it in your editor:

[colors]
bg     = "#0e0e10"
accent = "#8b5cf6"
error  = "#ff6b6b"

[typography]
font_family = "JetBrains Mono"

# Per-agent overrides (quote names with spaces or parentheses).
[agents."Claude Code (Personal)"]
accent = "#d97757"

For an agent's accent color, the first match wins: [agents."<name>"].accent in theme.toml[[agents]] color = "..." in config.toml → the agent's per-kind brand default. A WCAG-luminance fallback then swaps any color that would wash out against the dark surface (> 0.85 relative luminance) for colors.agent_fallback.

The header refresh button reloads theme.toml alongside config.toml, so edits take effect without restarting Aura. The full schema lives in .design/customization.md.

Installation

Aura is a system-tray indicator — like wifi or volume in your panel. The installer wires up autostart by default so the icon is present the moment you log in:

Platform What gets installed
Linux ~/.local/bin/aura + a systemd user service (enabled & started) + an XDG .desktop entry for the app menu
macOS Aura.app in /Applications + a launchd LaunchAgent (loaded now + at every login)
Windows aura.exe in %LOCALAPPDATA%\Programs\Aura + a Startup-folder shortcut (autostart) + a Start Menu shortcut

Left-click the tray icon to open Aura's modal; left-click again to close. Right-click for an explicit menu with Show Aura and Quit Aura. just stop / systemctl --user stop aura (Linux) and just stop-windows (Windows) are equivalent CLI exits.

Grab a prebuilt release archive (next section) or build from source with Cargo (Rust 1.80+).

Making the tray icon always visible

On Plasma / GNOME the icon may land in the "hidden" overflow group first. Promote it so it sits permanently next to wifi/volume:

  • KDE Plasma — right-click the system tray → Configure System Tray → Entries → find Aura → set Visibility: Always shown.
  • GNOME — install the AppIndicator and KStatusNotifierItem Support extension if you don't have it; aura then appears in the panel by default.
  • macOS — the menu-bar icon is always visible; nothing to configure.
  • Windows — click the ^ overflow arrow in the tray, drag the Aura icon to the always-visible area.

Modal placement on Wayland

On X11, Windows, and macOS, the modal opens in the bottom-right corner (where the tray icon usually lives). On Wayland (KWin, Mutter, sway) the compositor decides where windows go — the Wayland protocol forbids clients from positioning regular toplevel surfaces — so KWin will typically center the modal instead. The modal's height is still capped so it never overlaps a bottom taskbar.

If you'd like exact bottom-right placement on KDE Plasma / Wayland, add a KWin window rule:

  1. System Settings → Window Management → Window Rules → Add New.
  2. Window class (substring match): aura.
  3. Add property Position → set the value to e.g. [screen_width - 540, screen_height - panel_height - 660] (Force = Apply Initially).
  4. Apply. The next time Aura's modal opens it will land where you set it.

System dependencies (Linux)

# Debian/Ubuntu
sudo apt install build-essential pkg-config libgtk-3-dev \
                 libxkbcommon-x11-dev libxcb1-dev libxcb-render0-dev \
                 libxcb-shape0-dev libxcb-xfixes0-dev libfontconfig-dev

The runtime dependencies (libgtk-3-0, libxkbcommon-x11-0, libxcb1, libxcb-render0, libxcb-shape0, libxcb-xfixes0, libfontconfig1) are also needed at install-from-release time — the -dev packages above cover them.

System dependencies (macOS)

xcode-select --install                  # AppKit / linker
brew install librsvg                    # only needed if you want a real .icns

The release tarball is unsigned, so on first launch macOS will quarantine it. Either right-click Aura.appOpen and confirm, or strip the flag:

xattr -dr com.apple.quarantine /Applications/Aura.app

Claude Code OAuth tokens are stored in the macOS Keychain on Darwin (service Claude Code-credentials); Aura reads them from there automatically. If you get a "Keychain read failed" warning, run Claude Code at least once to populate the entry, then restart Aura.

System dependencies (Windows)

No system packages required — the MSVC C runtime ships with Windows. To build from source you'll need:

# Install Rust (https://rustup.rs) and the MSVC build tools
# (Visual Studio "Desktop development with C++" workload or VS Build Tools).
rustup target add x86_64-pc-windows-msvc      # default on Windows hosts

On Windows Claude Code stores OAuth tokens in Credential Manager (target Claude Code-credentials); Aura reads them from there automatically, falling back to %USERPROFILE%\.claude\.credentials.json for legacy installs. If you get a "Credential Manager read failed" warning, run Claude Code at least once to populate the entry, then restart Aura.

Install from GitHub Releases

Published releases include tarballs (Linux/macOS) and a zip (Windows) containing the aura binary plus the platform autostart artifact. Plugins (incl. RTK Gains) are shipped as separate downloads and installed with aura plugin add:

  • Linux x86_64 (gnu) — x86_64-unknown-linux-gnu
  • Linux x86_64 (musl) — x86_64-unknown-linux-musl
  • Linux aarch64 (gnu) — aarch64-unknown-linux-gnu
  • macOS Intel — x86_64-apple-darwin (ships Aura.app + com.aura.agent-usage.plist)
  • macOS Apple Silicon — aarch64-apple-darwin
  • Windows x86_64 — x86_64-pc-windows-msvc (ships aura.exe + install.ps1)
  • Windows aarch64 — aarch64-pc-windows-msvc (experimental)

Note: the musl Linux artifact and the aarch64 Windows artifact are still experimental. macOS archives are built and signed best-effort — unsigned bundles will be quarantined by Gatekeeper; see the macOS deps section above. Windows binaries are unsigned: SmartScreen may prompt on first run.

Run the installer — it auto-detects your host, downloads the matching archive, verifies its checksum, and wires up autostart:

# Linux / macOS
curl -fsSL https://raw.githubusercontent.com/Rfluid/aura/main/install.sh | bash
# Windows (PowerShell)
iex (irm https://raw.githubusercontent.com/Rfluid/aura/main/scripts/install.ps1)

Make sure ~/.local/bin (Linux/macOS) or %LOCALAPPDATA%\Programs\Aura (Windows) is on PATH.

Build from source

One-shot install

./install.sh        # auto-detects Linux/macOS and wires up autostart
# Windows
powershell -ExecutionPolicy Bypass -File .\scripts\install.ps1

Or, with just:

just install                 # build + install + autostart (Linux/macOS)
just install-windows         # build + install + autostart (Windows)

Manual (Linux)

cargo build --release -p aura
install -Dm755 target/release/aura ~/.local/bin/aura

# App-menu entry + icon (the tray icon itself is delivered inline by
# Aura over D-Bus, but the .desktop file lets the app menu find Aura).
sed "s|AURA_EXEC|$HOME/.local/bin/aura|" packaging/aura.desktop \
    > ~/.local/share/applications/aura.desktop
install -Dm644 packaging/aura.svg \
    ~/.local/share/icons/hicolor/scalable/apps/aura.svg
update-desktop-database ~/.local/share/applications 2>/dev/null || true
gtk-update-icon-cache -f -t ~/.local/share/icons/hicolor 2>/dev/null || true

# Autostart at every login via a systemd user service.
install -Dm644 packaging/aura.service ~/.config/systemd/user/aura.service
systemctl --user daemon-reload
systemctl --user enable --now aura

Manual (macOS)

cargo build --release -p aura
install -m 755 target/release/aura ~/.local/bin/aura

./scripts/build-macos-app.sh target/release/aura target/release
cp -R target/release/Aura.app /Applications/Aura.app

# Autostart at every login via a launchd LaunchAgent.
install -m 644 packaging/com.aura.agent-usage.plist \
    ~/Library/LaunchAgents/com.aura.agent-usage.plist
launchctl bootstrap "gui/$(id -u)" \
    ~/Library/LaunchAgents/com.aura.agent-usage.plist

Manual (Windows)

cargo build --release -p aura

$dst = Join-Path $env:LOCALAPPDATA 'Programs\Aura'
New-Item -ItemType Directory -Force -Path $dst | Out-Null
Copy-Item -Force target\release\aura.exe "$dst\aura.exe"

# Startup-folder shortcut (autostart at sign-in, minimised to tray).
$wsh = New-Object -ComObject WScript.Shell
$lnk = $wsh.CreateShortcut((Join-Path ([Environment]::GetFolderPath('Startup')) 'Aura.lnk'))
$lnk.TargetPath       = "$dst\aura.exe"
$lnk.WorkingDirectory = $dst
$lnk.WindowStyle      = 7
$lnk.Save()

Common commands

Command What it does
just run Launch Aura (debug build) without installing
just start / just stop / just status Start, stop, or check the running aura process (Linux/macOS)
just start-windows / just stop-windows Same, for Windows
just uninstall / just uninstall-windows Remove binaries + autostart artifacts + launcher (keeps config & state)

just uninstall also clears the KDE window rule and any opt-in LaunchAgent / Startup-folder shortcut — you don't have to remember which install path you took.

Updating

When Aura notices a newer GitHub release on startup it shows an Update available · vX.Y.Z chip in the modal header. Clicking it opens this section. The simple, dependency-free path is two curls / two iexs — no cargo, no just, no checkout required:

# Linux / macOS
curl -fsSL https://raw.githubusercontent.com/Rfluid/aura/main/uninstall.sh | bash
curl -fsSL https://raw.githubusercontent.com/Rfluid/aura/main/install.sh   | bash
# Windows (PowerShell)
iex (irm https://raw.githubusercontent.com/Rfluid/aura/main/scripts/uninstall.ps1)
iex (irm https://raw.githubusercontent.com/Rfluid/aura/main/scripts/install.ps1)

The uninstall script stops the running tray, removes the binary + autostart artifacts, and clears the KDE keepalive rule (see Uninstall for the full list). The install script then fetches the latest GitHub release archive, verifies its checksum, and puts the new binary back in place — autostart and all. Your config and state are preserved through both halves.

The GitHub fetch behind the header chip sends a User-Agent: aura/<version> header (required by GitHub's API) and your source IP. No cookies, no auth, no body. To mute the chip without uninstalling, set [update] dismiss_all = true in ~/.config/aura/config.toml — that skips the network call entirely.

From a cloned checkout

If you have the repo cloned and built from source, just update (or just update-windows) does the equivalent locally — it calls just uninstall then just install, which in turn shell out to the same uninstall.sh / install.sh scripts above.

Updating only the running binary (advanced)

The installer always restarts the tray on macOS (launchctl kickstart -k) and Windows (Stop-Process before copy). On Linux it calls systemctl --user enable --now aura, which is a no-op when the unit is already running — so if you skipped the two-curl flow and just swapped binaries you'll need to bounce the unit:

# Linux — after dropping a new binary in ~/.local/bin/aura:
systemctl --user restart aura

Or, when you opted out of the systemd autostart entirely:

pkill -x aura && ~/.local/bin/aura >/dev/null 2>&1 &
disown

Uninstall

# Linux / macOS
just uninstall            # disables autostart, kills the running tray,
                          # removes binaries + launcher + systemd unit
                          # (Linux) / LaunchAgent + Aura.app (macOS),
                          # and clears the KDE keepalive window rule
# Windows (PowerShell)
just uninstall-windows    # stops aura.exe and removes the binary +
                          # Start Menu / Startup-folder shortcuts

Your config and state are preserved (~/.config/aura/config.toml and ~/.local/share/aura/state.json on Linux; the equivalent OS-specific dirs on macOS / Windows). Delete those by hand if you want a full wipe.

Compatibility

Aura ships and is verified end-to-end on Linux (KDE Plasma 6 / Wayland), macOS 12+, and Windows 10/11 — tray icon, modal, autostart, single-click activation, focus-loss dismiss, and the installer all work on each. The table below also lists Linux compositors that share the same StatusNotifierItem code path but haven't been explicitly verified — please open an issue if anything goes wrong, with the desktop env / compositor version.

Platform Desktop / Compositor Tray protocol Status
Linux KDE Plasma 6 (Wayland / KWin) StatusNotifierItem (ksni) ✅ Tested — install.sh auto-installs the KWin "skip taskbar" rule for the keepalive
Linux KDE Plasma 6 (X11) StatusNotifierItem (ksni) ⚠️ Untested — same code, position is honored natively so modal opens bottom-right
Linux KDE Plasma 5 StatusNotifierItem (ksni) ⚠️ Untested — Plasma 5's plasmashellrc panel-thickness lookup may differ
Linux GNOME 45+ (Wayland / Mutter) StatusNotifierItem via AppIndicator extension ⚠️ Untested — extension is required for the icon to appear
Linux sway / Hyprland / wlroots StatusNotifierItem ⚠️ Untested — depends on a status-bar that honours SNI (Waybar etc.)
Linux XFCE / Cinnamon / MATE StatusNotifierItem ⚠️ Untested — these spec'ed StatusNotifierItem support, should work
macOS 12+ AppKit menu-bar item ✅ Tested — tray-icon's native AppKit backend, single-click activation, launchd autostart
Windows 10/11 Shell_NotifyIcon ✅ Tested — tray-icon's native Win32 backend, single-click activation, Startup-folder autostart

Pull requests confirming or fixing any of the ⚠️ rows are welcome — see Under the hood for the relevant code paths.

Under the hood

A few decisions worth knowing about if you're contributing or debugging:

Linux tray backend: ksni, not libayatana-appindicator

We use ksni — a direct StatusNotifierItem D-Bus implementation — instead of the more common tray-icon crate with its gtk (libayatana-appindicator) feature. AppIndicator collapses every click into "show context menu" and forces a GTK main loop on its own thread; ksni surfaces Activate() as a callback (single click → action) and runs its own lightweight D-Bus loop. The single-click open / close UX you see is only possible because of that.

The keepalive window

GPUI 0.2's Wayland event loop exits the moment state.windows.is_empty() (source). If aura only had the modal, closing it would kill the tray process. So we open a tiny aura-keepalive window on startup and never close it. KDE renders it as a real toplevel (Wayland's show: false is ignored), so:

  • it opens off-screen at (-9999, -9999) and is minimised immediately;
  • it registers on_window_should_close → false so the WM's "close window" action becomes a no-op (the tray can't be killed by a stray click in the task manager);
  • install.sh writes a KWin rule (~/.config/kwinrulesrc) that forces Skip Taskbar / Skip Pager / Skip Switcher on its app_id.

On GNOME / sway / etc. the keepalive may still appear in the task-bar / overview. Patches to add equivalent rules per WM are welcome.

Modal placement on Wayland

Wayland's xdg_toplevel protocol forbids client-side positioning — the compositor decides where windows go. GPUI 0.2 always uses xdg_toplevel (never xdg_popup), so KWin / Mutter / sway ignore our requested origin and typically center the modal. On X11, Windows, and macOS, our requested bottom-right corner is honored natively.

To pin the modal to a specific position on KDE / Wayland, add a window rule under System Settings → Window Management → Window Rules with Window class substring match aura and a forced Position.

Why we cap the modal height (and how)

Some pages produce more content than fits in the initial 640 px modal. GPUI's auto-resize lets the window grow downward to fit — and would otherwise overlap a bottom taskbar. On KDE Plasma we parse ~/.config/plasmashellrc to get the exact panel thickness and cap the resize at display_bottom − thickness. On everything else we use a 120 px blind reserve, which clears all common taskbar / Dock heights at a small cost in usable space.

Roadmap

Shipped

  • Claude Code usage integration (~/.claude JSONL scan, OAuth via Keychain / Credential Manager)
  • Codex usage integration (~/.codex session scan)
  • Gemini usage integration (~/.gemini session scan)
  • Multi-profile config + persisted selection across sessions
  • Plugin runner (subprocess + JSON IPC); RTK Gains shipped as opt-in plugin
  • Linux support (systemd user service · ksni StatusNotifierItem · KDE / GNOME / sway compatible)
  • macOS support (Apple Silicon + Intel; menu-bar Aura.app + launchd autostart)
  • Windows support (x86_64 + aarch64; Shell_NotifyIcon tray + Startup-folder autostart)
  • Per-DE polish: auto-installed KWin rule on KDE to hide the keepalive surface
  • Update button — header chip that surfaces a newer GitHub release on startup and links to the two-curl update flow. Design: docs/plans/update-button.md

Next up

  • Plugin authoring guide + example plugin (see docs/plugin-authoring.md and plugins/hello/)
  • Plugin discovery (local scan of ~/.config/aura/plugins/) + aura plugin add|list|remove
  • Forecast tab — project end-of-window usage (session, weekly, …) from the current burn rate, shown alongside each quota bar; rolls out per agent: Claude Code → Codex → Gemini. Design: docs/forecast-tab.md
  • Custom command agents (BYOA — Bring Your Own Agent via a shell command)
  • Historical usage charts (daily / weekly trend in the modal)
  • Per-project usage breakdown (where agents expose project-scoped data)

Later

  • Plugin registry (aura plugin install <name>)
  • Signed macOS bundles + notarization
  • Signed Windows binaries (SmartScreen-clean)

Sponsor

See SPONSOR.md for ways to support Aura.

Contributing

See CONTRIBUTING.md for local setup, development workflow, and pull request guidance.

License

MIT