enieuwy/showy-quota

Always-on AI plan quota strips for SketchyBar, Zellij, and tmux, driven by CodexBar.

Shell

20

213 commits

updated Sep 27, 2026

See the code

README

showy-quota

Always-on AI plan quota strips for SketchyBar, Zellij, and tmux, driven by CodexBar.

Beautiful, themeable, minimal.

showy-quota running across SketchyBar and a Zellij terminal on macOS

showy-quota running across SketchyBar and a Zellij terminal on macOS


showy-quota zellij strip running inside Termius on iPhone 16 Pro, showing four AI provider countdowns

showy-quota's Zellij strip on an iPhone — four AI providers, real quotas, mid-session


codexbar serve → http://127.0.0.1:8080/health + /usage
       ▲
       │ auto-started by plugin/fetcher when absent
       │
       ├──► showy-quota-zellij.wasm              (standalone Zellij plugin)
       │
       ▼
bin/showy-quota-fetch     ←  shared cache envelope + flock + last-known-good
       │  ~/.cache/showy-quota/usage.json (envelope: source + providers)
       ├──► bin/showy-quota-state                 (stable provider/layout state JSON)
       ├──► adapters/sketchybar/plugins/showy_quota.sh    (native SketchyBar rows/rings + icons)
       ├──► bin/showy-quota-tmux-bar             (tmux #[…] markup for status-right)
       ├──► bin/showy-quota-zellij-bar           (advanced zjstatus pipe segment)
       └──► adapters/agent-cli/showy-quota-statusline  (agent-CLI status line strip)

Features

  • Zero auth/config: Relies entirely on CodexBar for credentials and parsing.
  • Provider status (SketchyBar): Icons automatically tint yellow (minor/maintenance) or red (major/critical) during an outage. Clicking a degraded icon opens the provider's official status page.
  • Pacing & thresholds: Renders proportional pacing markers where the surface supports them and color-codes usage (good/warn/bad) based on configurable remaining-quota and time thresholds.
  • Themeable: Ships with Catppuccin, Nord, Dracula, Tokyo Night, and others.
  • Low overhead: Host bars share one cached fetcher; Zellij can use a single WASM artifact.
  • Ring mode (SketchyBar, optional): One ring per model family with the provider logo inside, stacked bars for shorter windows, and a hover popup per provider. Rows stay the default; ring mode needs the SketchyBar fork (see SketchyBar wiring).

Quickstart

  1. Install and enable CodexBar. It is the only thing that talks to providers.

    brew install --cask steipete/tap/codexbar          # macOS
    # CLI tarball / Linux: https://github.com/steipete/CodexBar/releases
    codexbar usage --format json | jq length           # should print 1 or more
    

    On macOS, cookie-based providers also need Full Disk Access for CodexBar in System Settings → Privacy & Security. If jq length prints 0, fix CodexBar before continuing — showy-quota has nothing to paint without it.

  2. Install showy-quota.

    Recommended release tarball path for shell integrations (SketchyBar, tmux, and the advanced Zellij/zjstatus driver):

    # Pick the asset for your platform: macos-arm64, macos-x86_64, or linux-x86_64.
    VERSION=$(curl -fsSL https://api.github.com/repos/enieuwy/showy-quota/releases/latest | jq -r '.tag_name | sub("^v"; "")')
    TARGET=macos-arm64
    curl -LO "https://github.com/enieuwy/showy-quota/releases/download/v${VERSION}/showy-quota-${VERSION}-${TARGET}.tar.gz"
    curl -LO "https://github.com/enieuwy/showy-quota/releases/download/v${VERSION}/showy-quota-${VERSION}-${TARGET}.tar.gz.sha256"
    shasum -a 256 -c "showy-quota-${VERSION}-${TARGET}.tar.gz.sha256"
    # If your system uses GNU coreutils, use:
    # sha256sum -c "showy-quota-${VERSION}-${TARGET}.tar.gz.sha256"
    tar xzf "showy-quota-${VERSION}-${TARGET}.tar.gz"
    cd "showy-quota-${VERSION}"
    make install-copy             # copies runtime files into ~/.local/share/showy-quota
    

    Per-platform tarballs include the prebuilt native showy-quota-render binary beside the shell entry points, so installing from a release does not require Rust or Cargo.

    Developer/source mode keeps symlinks into your checkout:

    git clone https://github.com/enieuwy/showy-quota && cd showy-quota
    make doctor                   # bash 4+, jq 1.6+, codexbar present
    make install                  # symlinks bin/* into ~/.local/bin
    

    Zellij's standalone plugin can still be installed by downloading showy-quota-zellij.wasm; see docs/plugin.md. From source, make install-plugin builds and installs it. make install-copy, make install, and make install-plugin refuse to clobber existing files unless you run with FORCE=1.

    Shell completions (Bash, zsh, fish) for showy-quota, showy-quota-fetch, and showy-quota-state: make install-completions (also part of make install-all). For zsh, add ${XDG_DATA_HOME:-$HOME/.local/share}/zsh/site-functions to fpath before compinit.

  3. Wire a UI. Pick the UI(s) you use:

    • SketchyBar: make install-copy-sketchybar for a release/copy install (or make install-sketchybar for dev symlinks), then add source "$ITEM_DIR/showy_quota.sh" to your sketchybarrc and reload.
    • tmux: use the TPM wrapper or paste the snippet in tmux wiring into ~/.tmux.conf.
    • Zellij: install showy-quota-zellij.wasm, paste the layout fragment. See docs/zellij.md and docs/plugin.md.
    • Agent CLI statusline: point Claude Code (or any command-backed status line) at adapters/agent-cli/showy-quota-statusline; see docs/statusline.md.

SketchyBar wiring

Install the SketchyBar item/plugin, then add the item declaration to ~/.config/sketchybar/sketchybarrc after ITEM_DIR and PLUGIN_DIR are defined:

make install-sketchybar
source "$ITEM_DIR/showy_quota.sh"

Then reload SketchyBar (sketchybar --reload or quit + relaunch) once to load the trigger item. One icon + bar + label triple appears per provider currently fetching usage data; later provider adds/removals land on the next plugin tick without another reload.

Set SHOWY_QUOTA_SKETCHYBAR_BODY=ring for one ring per model family instead of rows, with hover popups per window (see docs/sketchybar.md "Strip body: rows or ring"). Ring mode needs the SketchyBar fork github.com/enieuwy/SketchyBar — the ring item (upstream PR #817) and the badges (upstream PR #816), neither merged upstream yet. Build the fork's local/v2.24-integration branch (its master tracks upstream and has no ring); on stock SketchyBar the plugin falls back to rows.

showy-quota SketchyBar ring strip: one ring per model family with countdown labels, pace ticks and bars

showy-quota ring hover popup for Command Code: a mini gauge, % left, window, length, pace and reset per window

Ring mode: the strip, and the popup when you point at a provider

Zellij wiring

Two pieces:

  1. Plugin pane — install showy-quota-zellij.wasm and paste adapters/zellij/layout-pane.kdl.fragment into your default layout. It declares one visible standalone plugin pane; no zjstatus or feeder loop is needed.
  2. Detail keybind — paste adapters/zellij/detail-pane.kdl.fragment into your keybinds block. Default is Alt /.

Reload Zellij to pick up the new layout/keybind. Advanced users who want showy-quota inside an existing multi-widget zjstatus row can keep using showy-quota-zellij-pipe; see docs/zellij.md.

tmux wiring

TPM users can install the wrapper directly:

set -g @plugin 'enieuwy/showy-quota'

# Optional: bind the detail popup. Pick any prefix-relative key you prefer.
set -g @showy-quota-popup-key '/'

The TPM wrapper adds the existing bin/showy-quota-tmux-bar renderer to status-right; it does not introduce a second tmux implementation. Without TPM, wire the same renderer manually:

# Use the absolute path — tmux's PATH at server start typically lacks ~/.local/bin.
CB_BIN="$HOME/.local/bin"
cat >> ~/.tmux.conf <<TMUX
set -g status-right-length 300
if -F '#{m:*showy-quota-tmux-bar*,#{status-right}}' '' 'set -ag status-right " #(${CB_BIN}/showy-quota-tmux-bar)"'
bind-key "/" display-popup -E -h 36 -w 92 -T "CodexBar usage" 'config="\${XDG_CONFIG_HOME:-\$HOME/.config}/showy-quota/config.env"; [ -r "\$config" ] && . "\$config"; while :; do clear; "\${SHOWY_QUOTA_CODEXBAR_BIN:-codexbar}" usage; sleep 30; done'
TMUX
tmux source ~/.tmux.conf

No watch(1) dependency — the popup uses a tiny shell loop so this works on a stock macOS install.

Terminal rendering modes

Terminal strips default to an auto mode that picks a body layout per provider:

  • dual (default for most providers): a primary-over-secondary half-block layout. Each window is colored by its remaining-quota severity and dimmed when it is a weekly/monthly cap; both rows show a pacing marker (the elapsed color tints the upper half for the primary window and the lower half for the secondary). Body width is 12 cells. dual terminal rendering layout
  • mono3 (default for gemini, cursor): packs primary, secondary, and tertiary into a single sextant cell per column with top/middle/bottom rows. Uses a single provider-level foreground color and mono_markers pacing separators. Providers whose windows share one billing cycle (same reset and window length, e.g. Cursor's Total/Auto/API) stay at full brightness and show a single pacing marker. mono3 terminal rendering layout
  • mono4 (opt-in): packs four per-pool windows (e.g. Antigravity's Gemini and Claude+GPT session/weekly pools, from extraRateWindows) into a single octant cell per column. Like mono3 but four lanes — requires an octant-capable terminal (Ghostty, kitty, WezTerm); run python3 docs/scripts/preview-quad-octants.py to test yours. mono4 terminal rendering layout
  • dual2 (auto-detected for model-pooled providers like antigravity): splits the provider into one standalone dual per pool (AGᴳ for Gemini, AGᶜ for Claude+GPT), each from extraRateWindows and rendered by the normal half-block dual path. Half-blocks render in every terminal (unlike mono4). auto engages the split when a provider's extras carry all its positional slots; a single pool stays one plain dual (Antigravity via OAuth reports only Gemini). Force the split per provider with SHOWY_QUOTA_PROVIDER_MODES=<provider>=dual2. dual2 terminal rendering layout

Customize terminal layout with SHOWY_QUOTA_TERMINAL_BAR_MODE=dual|dual2|mono3|mono4. For per-provider auto-mode selection and marker behavior, use SHOWY_QUOTA_PROVIDER_MODES (e.g. antigravity=mono4), SHOWY_QUOTA_MONO_COLOR_MODE, and SHOWY_QUOTA_MONO_MARKERS.

Stuck? bin/showy-quota --diagnose (or make diagnose) prints exactly the state a bug report needs; bin/showy-quota --diagnose --json emits the same diagnostic surface as stable machine-readable JSON. Both include your absolute paths and serve URL, so add --redact before pasting anywhere public: it collapses each path to its basename and hides URL hosts while keeping ports, versions and provider counts, and sets "redacted": true in the JSON.

Automation & prompts

These subcommands read the same provider metrics the bars use — see docs/automation.md for the full reference (exit codes, --json schema, hook/cron/at/systemd recipes, and prompt snippets for starship, powerlevel10k, and plain PS1).

  • showy-quota guard gates CI, cron, and agent hooks on quota thresholds with stable exit codes (0 pass, 1 breach, 2 unusable data, 3 usage):

    # Fail (exit 1) if codex or claude drops below 15% remaining
    showy-quota guard --provider codex,claude --min-remaining 15
    

    Agent hooks can add --no-fetch to evaluate a warm cache without starting provider collection.

  • showy-quota prompt prints a one-line segment (CX 92% 3:02) for the worst-remaining provider. It reads the cache as-is, so it never blocks a shell. In starship:

    # ~/.config/starship.toml
    [custom.showy_quota]
    command = 'showy-quota prompt'
    when = true
    shell = ['bash', '--noprofile', '--norc']
    format = '[$output]($style) '
    style = 'bold yellow'
    
  • showy-quota run [guard options] -- <command> runs a command only when its guard passes and forwards its exit code; --wait-max waits for known resets instead of failing. showy-quota next-reset prints the seconds until a window refills, for at, cron, and systemd timers.

  • showy-quota pick prints the provider with the most remaining quota, for routing work between models.

  • showy-quota refresh forces a cache refresh and repaints the SketchyBar, tmux, and shell Zellij bars that are running.

  • showy-quota serve status|restart|stop inspects or controls the managed codexbar serve; status only reads /health.

  • showy-quota --check-config lists config values that were rejected or clamped, and unknown SHOWY_QUOTA_* keys.

  • showy-quota-state --explain says why each provider is shown or hidden.

Requirements

  • macOS for SketchyBar. Zellij/tmux bars also work on Linux when CodexBar can fetch your chosen providers.
  • A CodexBar data source:
    • Zellij plugin: codexbar on the Zellij server PATH; the plugin starts codexbar serve by default, uses /health + /usage, and visibly marks CLI fallback as ⚠cli;
    • shell integrations: same managed serve path via showy-quota-fetch, with visible ⚠cli fallback. CodexBar's web-backed providers remain macOS-only; CLI/OAuth/API/local providers work where CodexBar supports them.
  • Shell integrations need bash 4+, jq 1.6+, and a date that understands either -j -f (BSD/macOS) or -d (GNU coreutils). make check-deps asserts the bash and jq floors and is the same check CI runs, so a passing local install and a passing CI leg mean the same thing. The standalone Zellij plugin does not need the shell scripts, bash, or jq.
  • SketchyBar integration also needs sketchybar on the PATH. Font icon mode needs sketchybar-app-font; SVG fallback icons need ImageMagick 7.1.1+ (magick), which renders third-party provider SVGs. Native usage rows do not need magick.
  • The Zellij/tmux renderers wrap each provider chunk in Powerline-Extra end caps (U+E0B6 / U+E0B4). Any Nerd Font ships these. For the standalone Zellij plugin with a non-Nerd font, set cap_left "" and cap_right "" in the plugin KDL; for tmux or advanced zjstatus, set SHOWY_QUOTA_CAP_LEFT= / SHOWY_QUOTA_CAP_RIGHT=. Terminal sextant modes have additional font notes in docs/zellij.md and docs/tmux.md.
  • Optional: flock for inter-process locking; falls back to an owner-scoped mkdir lock when missing.
  • Development/install commands are written for GNU-compatible make; on systems with a non-GNU default make, use gmake or invoke the scripts directly.

Configuration

The shell integrations (SketchyBar, tmux, and the Zellij shell renderers) read optional overrides from ~/.config/showy-quota/config.env. The standalone Zellij WASM plugin is configured with KDL keys instead (the same names without the SHOWY_QUOTA_ prefix, lowercased); see docs/plugin.md.

Config is optional; create it only for values you want to override. The full environment surface lives in share/config.env.example — most users only need these:

VariableEffect
SHOWY_QUOTA_THEMELoad a named built-in or user palette. default=unset (default palette)
SHOWY_QUOTA_PROVIDERSOrdered provider allow-list; empty renders CodexBar's enabled providers. default=empty
SHOWY_QUOTA_PROVIDERS_EXCLUDEProvider deny-list applied after the allow-list. default=empty
SHOWY_QUOTA_PROVIDER_ORDERStable render order without filtering. default=codex,claude,copilot,opencode,gemini
SHOWY_QUOTA_REFRESH_SECONDSFreshness contract: full-refresh cadence and CLI-fallback interval. Serve collection and /usage-poll defaults derive from it. default=120
SHOWY_QUOTA_MANAGE_SERVEStart codexbar serve automatically before CLI fallback; set 0 to disable. default=1
SHOWY_QUOTA_CODEXBAR_SERVE_URLLocal codexbar serve base URL; also sets the managed serve --port, so probing and startup always agree. Set empty to skip HTTP probing. default=http://127.0.0.1:8080
SHOWY_QUOTA_CODEXBAR_SERVE_TIMEOUT_SECONDSBounded positive timeout for local /health probes. configured default=10
SHOWY_QUOTA_CODEXBAR_SERVE_USAGE_TIMEOUT_SECONDSBounded positive timeout for local /usage probes. default=30
SHOWY_QUOTA_CODEXBAR_SERVE_REFRESH_INTERVAL_SECONDSCollection cadence for a managed codexbar serve. default=SHOWY_QUOTA_REFRESH_SECONDS
SHOWY_QUOTA_CODEXBAR_SERVE_REFRESH_SECONDS/usage re-read cadence when codexbar serve is available. default=SHOWY_QUOTA_REFRESH_SECONDS / 2
SHOWY_QUOTA_TIME_WARN_MINUTESUrgent countdown threshold. default=30
SHOWY_QUOTA_SKETCHYBAR_CLICKDefault SketchyBar click action; degraded icons open provider status URLs. default=open -b com.steipete.codexbar
SHOWY_QUOTA_VERTICAL_BAR_WIDTHBar width in cells for each --emit vertical line. default=16
SHOWY_QUOTA_VERTICAL_SORT--emit vertical line order: provider keeps CodexBar's blocks, urgency puts the window closest to running out first (ties keep provider order). default=provider
SHOWY_QUOTA_VERTICAL_RESET_CLOCKAppend each window's local reset clock to its --emit vertical line; 0 trades it back for six columns. default=1

Palette overrides use role-first primary keys such as SHOWY_QUOTA_PALETTE_PRIMARY_*; long-horizon windows are dimmed from the primary palette with SHOWY_QUOTA_PALETTE_DIM_SCALE after SHOWY_QUOTA_DIM_WINDOW_MINUTES. There are no separate secondary/tertiary palette overrides; see share/config.env.example for the full palette surface.

theme nameSketchyBar imageterminal / Zellij image
carbonfoxcarbonfox SketchyBar previewcarbonfox terminal preview
catppuccin-frappecatppuccin-frappe SketchyBar previewcatppuccin-frappe terminal preview
catppuccin-lattecatppuccin-latte SketchyBar previewcatppuccin-latte terminal preview
catppuccin-macchiatocatppuccin-macchiato SketchyBar previewcatppuccin-macchiato terminal preview
catppuccin-mochacatppuccin-mocha SketchyBar previewcatppuccin-mocha terminal preview
catppuccin-mocha-bluecatppuccin-mocha-blue SketchyBar previewcatppuccin-mocha-blue terminal preview
defaultdefault SketchyBar previewdefault terminal preview
draculadracula SketchyBar previewdracula terminal preview
gruvbox-darkgruvbox-dark SketchyBar previewgruvbox-dark terminal preview
nordnord SketchyBar previewnord terminal preview
tokyonighttokyonight SketchyBar previewtokyonight terminal preview

Verification

make doctor      # check runtime prerequisites
make test        # smoke tests over JSON fixtures
make plugin      # build showy-quota-zellij.wasm
make diagnose    # printable bug-report state (`bin/showy-quota --diagnose --json` for JSON)

Cache lives at ${XDG_CACHE_HOME:-~/.cache}/showy-quota/usage.json. If that file is corrupt, the fetcher moves it aside as usage.json.corrupt.<epoch>.<pid> and keeps only the newest few quarantine files for diagnostics. make clean clears cache artifacts.

How it stays cheap

  • tmux, SketchyBar, and advanced zjstatus share one cached fetcher. It prefers codexbar serve, starts it when absent, and marks CLI fallback as ⚠cli.
  • The standalone Zellij plugin uses the same serve-first shape and keeps in-memory last-known-good output per pane.

License

MIT — same as CodexBar.

Credits

CodexBar by Peter Steinberger does all the real work. This repo just paints its output onto status bars.

ai
ai-coding
api-quota
claude
codex
codexbar
dotfiles
gemini
macos
menubar
quota
ricing
sketchybar
statusline
tmux
zellij

enieuwy/showy-quota

Always-on AI plan quota strips for SketchyBar, Zellij, and tmux, driven by CodexBar.

Shell

20

213 commits

updated Sep 27, 2026

See the code

README

showy-quota

Always-on AI plan quota strips for SketchyBar, Zellij, and tmux, driven by CodexBar.

Beautiful, themeable, minimal.

showy-quota running across SketchyBar and a Zellij terminal on macOS

showy-quota running across SketchyBar and a Zellij terminal on macOS


showy-quota zellij strip running inside Termius on iPhone 16 Pro, showing four AI provider countdowns

showy-quota's Zellij strip on an iPhone — four AI providers, real quotas, mid-session


codexbar serve → http://127.0.0.1:8080/health + /usage
       ▲
       │ auto-started by plugin/fetcher when absent
       │
       ├──► showy-quota-zellij.wasm              (standalone Zellij plugin)
       │
       ▼
bin/showy-quota-fetch     ←  shared cache envelope + flock + last-known-good
       │  ~/.cache/showy-quota/usage.json (envelope: source + providers)
       ├──► bin/showy-quota-state                 (stable provider/layout state JSON)
       ├──► adapters/sketchybar/plugins/showy_quota.sh    (native SketchyBar rows/rings + icons)
       ├──► bin/showy-quota-tmux-bar             (tmux #[…] markup for status-right)
       ├──► bin/showy-quota-zellij-bar           (advanced zjstatus pipe segment)
       └──► adapters/agent-cli/showy-quota-statusline  (agent-CLI status line strip)

Features

  • Zero auth/config: Relies entirely on CodexBar for credentials and parsing.
  • Provider status (SketchyBar): Icons automatically tint yellow (minor/maintenance) or red (major/critical) during an outage. Clicking a degraded icon opens the provider's official status page.
  • Pacing & thresholds: Renders proportional pacing markers where the surface supports them and color-codes usage (good/warn/bad) based on configurable remaining-quota and time thresholds.
  • Themeable: Ships with Catppuccin, Nord, Dracula, Tokyo Night, and others.
  • Low overhead: Host bars share one cached fetcher; Zellij can use a single WASM artifact.
  • Ring mode (SketchyBar, optional): One ring per model family with the provider logo inside, stacked bars for shorter windows, and a hover popup per provider. Rows stay the default; ring mode needs the SketchyBar fork (see SketchyBar wiring).

Quickstart

  1. Install and enable CodexBar. It is the only thing that talks to providers.

    brew install --cask steipete/tap/codexbar          # macOS
    # CLI tarball / Linux: https://github.com/steipete/CodexBar/releases
    codexbar usage --format json | jq length           # should print 1 or more
    

    On macOS, cookie-based providers also need Full Disk Access for CodexBar in System Settings → Privacy & Security. If jq length prints 0, fix CodexBar before continuing — showy-quota has nothing to paint without it.

  2. Install showy-quota.

    Recommended release tarball path for shell integrations (SketchyBar, tmux, and the advanced Zellij/zjstatus driver):

    # Pick the asset for your platform: macos-arm64, macos-x86_64, or linux-x86_64.
    VERSION=$(curl -fsSL https://api.github.com/repos/enieuwy/showy-quota/releases/latest | jq -r '.tag_name | sub("^v"; "")')
    TARGET=macos-arm64
    curl -LO "https://github.com/enieuwy/showy-quota/releases/download/v${VERSION}/showy-quota-${VERSION}-${TARGET}.tar.gz"
    curl -LO "https://github.com/enieuwy/showy-quota/releases/download/v${VERSION}/showy-quota-${VERSION}-${TARGET}.tar.gz.sha256"
    shasum -a 256 -c "showy-quota-${VERSION}-${TARGET}.tar.gz.sha256"
    # If your system uses GNU coreutils, use:
    # sha256sum -c "showy-quota-${VERSION}-${TARGET}.tar.gz.sha256"
    tar xzf "showy-quota-${VERSION}-${TARGET}.tar.gz"
    cd "showy-quota-${VERSION}"
    make install-copy             # copies runtime files into ~/.local/share/showy-quota
    

    Per-platform tarballs include the prebuilt native showy-quota-render binary beside the shell entry points, so installing from a release does not require Rust or Cargo.

    Developer/source mode keeps symlinks into your checkout:

    git clone https://github.com/enieuwy/showy-quota && cd showy-quota
    make doctor                   # bash 4+, jq 1.6+, codexbar present
    make install                  # symlinks bin/* into ~/.local/bin
    

    Zellij's standalone plugin can still be installed by downloading showy-quota-zellij.wasm; see docs/plugin.md. From source, make install-plugin builds and installs it. make install-copy, make install, and make install-plugin refuse to clobber existing files unless you run with FORCE=1.

    Shell completions (Bash, zsh, fish) for showy-quota, showy-quota-fetch, and showy-quota-state: make install-completions (also part of make install-all). For zsh, add ${XDG_DATA_HOME:-$HOME/.local/share}/zsh/site-functions to fpath before compinit.

  3. Wire a UI. Pick the UI(s) you use:

    • SketchyBar: make install-copy-sketchybar for a release/copy install (or make install-sketchybar for dev symlinks), then add source "$ITEM_DIR/showy_quota.sh" to your sketchybarrc and reload.
    • tmux: use the TPM wrapper or paste the snippet in tmux wiring into ~/.tmux.conf.
    • Zellij: install showy-quota-zellij.wasm, paste the layout fragment. See docs/zellij.md and docs/plugin.md.
    • Agent CLI statusline: point Claude Code (or any command-backed status line) at adapters/agent-cli/showy-quota-statusline; see docs/statusline.md.

SketchyBar wiring

Install the SketchyBar item/plugin, then add the item declaration to ~/.config/sketchybar/sketchybarrc after ITEM_DIR and PLUGIN_DIR are defined:

make install-sketchybar
source "$ITEM_DIR/showy_quota.sh"

Then reload SketchyBar (sketchybar --reload or quit + relaunch) once to load the trigger item. One icon + bar + label triple appears per provider currently fetching usage data; later provider adds/removals land on the next plugin tick without another reload.

Set SHOWY_QUOTA_SKETCHYBAR_BODY=ring for one ring per model family instead of rows, with hover popups per window (see docs/sketchybar.md "Strip body: rows or ring"). Ring mode needs the SketchyBar fork github.com/enieuwy/SketchyBar — the ring item (upstream PR #817) and the badges (upstream PR #816), neither merged upstream yet. Build the fork's local/v2.24-integration branch (its master tracks upstream and has no ring); on stock SketchyBar the plugin falls back to rows.

showy-quota SketchyBar ring strip: one ring per model family with countdown labels, pace ticks and bars

showy-quota ring hover popup for Command Code: a mini gauge, % left, window, length, pace and reset per window

Ring mode: the strip, and the popup when you point at a provider

Zellij wiring

Two pieces:

  1. Plugin pane — install showy-quota-zellij.wasm and paste adapters/zellij/layout-pane.kdl.fragment into your default layout. It declares one visible standalone plugin pane; no zjstatus or feeder loop is needed.
  2. Detail keybind — paste adapters/zellij/detail-pane.kdl.fragment into your keybinds block. Default is Alt /.

Reload Zellij to pick up the new layout/keybind. Advanced users who want showy-quota inside an existing multi-widget zjstatus row can keep using showy-quota-zellij-pipe; see docs/zellij.md.

tmux wiring

TPM users can install the wrapper directly:

set -g @plugin 'enieuwy/showy-quota'

# Optional: bind the detail popup. Pick any prefix-relative key you prefer.
set -g @showy-quota-popup-key '/'

The TPM wrapper adds the existing bin/showy-quota-tmux-bar renderer to status-right; it does not introduce a second tmux implementation. Without TPM, wire the same renderer manually:

# Use the absolute path — tmux's PATH at server start typically lacks ~/.local/bin.
CB_BIN="$HOME/.local/bin"
cat >> ~/.tmux.conf <<TMUX
set -g status-right-length 300
if -F '#{m:*showy-quota-tmux-bar*,#{status-right}}' '' 'set -ag status-right " #(${CB_BIN}/showy-quota-tmux-bar)"'
bind-key "/" display-popup -E -h 36 -w 92 -T "CodexBar usage" 'config="\${XDG_CONFIG_HOME:-\$HOME/.config}/showy-quota/config.env"; [ -r "\$config" ] && . "\$config"; while :; do clear; "\${SHOWY_QUOTA_CODEXBAR_BIN:-codexbar}" usage; sleep 30; done'
TMUX
tmux source ~/.tmux.conf

No watch(1) dependency — the popup uses a tiny shell loop so this works on a stock macOS install.

Terminal rendering modes

Terminal strips default to an auto mode that picks a body layout per provider:

  • dual (default for most providers): a primary-over-secondary half-block layout. Each window is colored by its remaining-quota severity and dimmed when it is a weekly/monthly cap; both rows show a pacing marker (the elapsed color tints the upper half for the primary window and the lower half for the secondary). Body width is 12 cells. dual terminal rendering layout
  • mono3 (default for gemini, cursor): packs primary, secondary, and tertiary into a single sextant cell per column with top/middle/bottom rows. Uses a single provider-level foreground color and mono_markers pacing separators. Providers whose windows share one billing cycle (same reset and window length, e.g. Cursor's Total/Auto/API) stay at full brightness and show a single pacing marker. mono3 terminal rendering layout
  • mono4 (opt-in): packs four per-pool windows (e.g. Antigravity's Gemini and Claude+GPT session/weekly pools, from extraRateWindows) into a single octant cell per column. Like mono3 but four lanes — requires an octant-capable terminal (Ghostty, kitty, WezTerm); run python3 docs/scripts/preview-quad-octants.py to test yours. mono4 terminal rendering layout
  • dual2 (auto-detected for model-pooled providers like antigravity): splits the provider into one standalone dual per pool (AGᴳ for Gemini, AGᶜ for Claude+GPT), each from extraRateWindows and rendered by the normal half-block dual path. Half-blocks render in every terminal (unlike mono4). auto engages the split when a provider's extras carry all its positional slots; a single pool stays one plain dual (Antigravity via OAuth reports only Gemini). Force the split per provider with SHOWY_QUOTA_PROVIDER_MODES=<provider>=dual2. dual2 terminal rendering layout

Customize terminal layout with SHOWY_QUOTA_TERMINAL_BAR_MODE=dual|dual2|mono3|mono4. For per-provider auto-mode selection and marker behavior, use SHOWY_QUOTA_PROVIDER_MODES (e.g. antigravity=mono4), SHOWY_QUOTA_MONO_COLOR_MODE, and SHOWY_QUOTA_MONO_MARKERS.

Stuck? bin/showy-quota --diagnose (or make diagnose) prints exactly the state a bug report needs; bin/showy-quota --diagnose --json emits the same diagnostic surface as stable machine-readable JSON. Both include your absolute paths and serve URL, so add --redact before pasting anywhere public: it collapses each path to its basename and hides URL hosts while keeping ports, versions and provider counts, and sets "redacted": true in the JSON.

Automation & prompts

These subcommands read the same provider metrics the bars use — see docs/automation.md for the full reference (exit codes, --json schema, hook/cron/at/systemd recipes, and prompt snippets for starship, powerlevel10k, and plain PS1).

  • showy-quota guard gates CI, cron, and agent hooks on quota thresholds with stable exit codes (0 pass, 1 breach, 2 unusable data, 3 usage):

    # Fail (exit 1) if codex or claude drops below 15% remaining
    showy-quota guard --provider codex,claude --min-remaining 15
    

    Agent hooks can add --no-fetch to evaluate a warm cache without starting provider collection.

  • showy-quota prompt prints a one-line segment (CX 92% 3:02) for the worst-remaining provider. It reads the cache as-is, so it never blocks a shell. In starship:

    # ~/.config/starship.toml
    [custom.showy_quota]
    command = 'showy-quota prompt'
    when = true
    shell = ['bash', '--noprofile', '--norc']
    format = '[$output]($style) '
    style = 'bold yellow'
    
  • showy-quota run [guard options] -- <command> runs a command only when its guard passes and forwards its exit code; --wait-max waits for known resets instead of failing. showy-quota next-reset prints the seconds until a window refills, for at, cron, and systemd timers.

  • showy-quota pick prints the provider with the most remaining quota, for routing work between models.

  • showy-quota refresh forces a cache refresh and repaints the SketchyBar, tmux, and shell Zellij bars that are running.

  • showy-quota serve status|restart|stop inspects or controls the managed codexbar serve; status only reads /health.

  • showy-quota --check-config lists config values that were rejected or clamped, and unknown SHOWY_QUOTA_* keys.

  • showy-quota-state --explain says why each provider is shown or hidden.

Requirements

  • macOS for SketchyBar. Zellij/tmux bars also work on Linux when CodexBar can fetch your chosen providers.
  • A CodexBar data source:
    • Zellij plugin: codexbar on the Zellij server PATH; the plugin starts codexbar serve by default, uses /health + /usage, and visibly marks CLI fallback as ⚠cli;
    • shell integrations: same managed serve path via showy-quota-fetch, with visible ⚠cli fallback. CodexBar's web-backed providers remain macOS-only; CLI/OAuth/API/local providers work where CodexBar supports them.
  • Shell integrations need bash 4+, jq 1.6+, and a date that understands either -j -f (BSD/macOS) or -d (GNU coreutils). make check-deps asserts the bash and jq floors and is the same check CI runs, so a passing local install and a passing CI leg mean the same thing. The standalone Zellij plugin does not need the shell scripts, bash, or jq.
  • SketchyBar integration also needs sketchybar on the PATH. Font icon mode needs sketchybar-app-font; SVG fallback icons need ImageMagick 7.1.1+ (magick), which renders third-party provider SVGs. Native usage rows do not need magick.
  • The Zellij/tmux renderers wrap each provider chunk in Powerline-Extra end caps (U+E0B6 / U+E0B4). Any Nerd Font ships these. For the standalone Zellij plugin with a non-Nerd font, set cap_left "" and cap_right "" in the plugin KDL; for tmux or advanced zjstatus, set SHOWY_QUOTA_CAP_LEFT= / SHOWY_QUOTA_CAP_RIGHT=. Terminal sextant modes have additional font notes in docs/zellij.md and docs/tmux.md.
  • Optional: flock for inter-process locking; falls back to an owner-scoped mkdir lock when missing.
  • Development/install commands are written for GNU-compatible make; on systems with a non-GNU default make, use gmake or invoke the scripts directly.

Configuration

The shell integrations (SketchyBar, tmux, and the Zellij shell renderers) read optional overrides from ~/.config/showy-quota/config.env. The standalone Zellij WASM plugin is configured with KDL keys instead (the same names without the SHOWY_QUOTA_ prefix, lowercased); see docs/plugin.md.

Config is optional; create it only for values you want to override. The full environment surface lives in share/config.env.example — most users only need these:

VariableEffect
SHOWY_QUOTA_THEMELoad a named built-in or user palette. default=unset (default palette)
SHOWY_QUOTA_PROVIDERSOrdered provider allow-list; empty renders CodexBar's enabled providers. default=empty
SHOWY_QUOTA_PROVIDERS_EXCLUDEProvider deny-list applied after the allow-list. default=empty
SHOWY_QUOTA_PROVIDER_ORDERStable render order without filtering. default=codex,claude,copilot,opencode,gemini
SHOWY_QUOTA_REFRESH_SECONDSFreshness contract: full-refresh cadence and CLI-fallback interval. Serve collection and /usage-poll defaults derive from it. default=120
SHOWY_QUOTA_MANAGE_SERVEStart codexbar serve automatically before CLI fallback; set 0 to disable. default=1
SHOWY_QUOTA_CODEXBAR_SERVE_URLLocal codexbar serve base URL; also sets the managed serve --port, so probing and startup always agree. Set empty to skip HTTP probing. default=http://127.0.0.1:8080
SHOWY_QUOTA_CODEXBAR_SERVE_TIMEOUT_SECONDSBounded positive timeout for local /health probes. configured default=10
SHOWY_QUOTA_CODEXBAR_SERVE_USAGE_TIMEOUT_SECONDSBounded positive timeout for local /usage probes. default=30
SHOWY_QUOTA_CODEXBAR_SERVE_REFRESH_INTERVAL_SECONDSCollection cadence for a managed codexbar serve. default=SHOWY_QUOTA_REFRESH_SECONDS
SHOWY_QUOTA_CODEXBAR_SERVE_REFRESH_SECONDS/usage re-read cadence when codexbar serve is available. default=SHOWY_QUOTA_REFRESH_SECONDS / 2
SHOWY_QUOTA_TIME_WARN_MINUTESUrgent countdown threshold. default=30
SHOWY_QUOTA_SKETCHYBAR_CLICKDefault SketchyBar click action; degraded icons open provider status URLs. default=open -b com.steipete.codexbar
SHOWY_QUOTA_VERTICAL_BAR_WIDTHBar width in cells for each --emit vertical line. default=16
SHOWY_QUOTA_VERTICAL_SORT--emit vertical line order: provider keeps CodexBar's blocks, urgency puts the window closest to running out first (ties keep provider order). default=provider
SHOWY_QUOTA_VERTICAL_RESET_CLOCKAppend each window's local reset clock to its --emit vertical line; 0 trades it back for six columns. default=1

Palette overrides use role-first primary keys such as SHOWY_QUOTA_PALETTE_PRIMARY_*; long-horizon windows are dimmed from the primary palette with SHOWY_QUOTA_PALETTE_DIM_SCALE after SHOWY_QUOTA_DIM_WINDOW_MINUTES. There are no separate secondary/tertiary palette overrides; see share/config.env.example for the full palette surface.

theme nameSketchyBar imageterminal / Zellij image
carbonfoxcarbonfox SketchyBar previewcarbonfox terminal preview
catppuccin-frappecatppuccin-frappe SketchyBar previewcatppuccin-frappe terminal preview
catppuccin-lattecatppuccin-latte SketchyBar previewcatppuccin-latte terminal preview
catppuccin-macchiatocatppuccin-macchiato SketchyBar previewcatppuccin-macchiato terminal preview
catppuccin-mochacatppuccin-mocha SketchyBar previewcatppuccin-mocha terminal preview
catppuccin-mocha-bluecatppuccin-mocha-blue SketchyBar previewcatppuccin-mocha-blue terminal preview
defaultdefault SketchyBar previewdefault terminal preview
draculadracula SketchyBar previewdracula terminal preview
gruvbox-darkgruvbox-dark SketchyBar previewgruvbox-dark terminal preview
nordnord SketchyBar previewnord terminal preview
tokyonighttokyonight SketchyBar previewtokyonight terminal preview

Verification

make doctor      # check runtime prerequisites
make test        # smoke tests over JSON fixtures
make plugin      # build showy-quota-zellij.wasm
make diagnose    # printable bug-report state (`bin/showy-quota --diagnose --json` for JSON)

Cache lives at ${XDG_CACHE_HOME:-~/.cache}/showy-quota/usage.json. If that file is corrupt, the fetcher moves it aside as usage.json.corrupt.<epoch>.<pid> and keeps only the newest few quarantine files for diagnostics. make clean clears cache artifacts.

How it stays cheap

  • tmux, SketchyBar, and advanced zjstatus share one cached fetcher. It prefers codexbar serve, starts it when absent, and marks CLI fallback as ⚠cli.
  • The standalone Zellij plugin uses the same serve-first shape and keeps in-memory last-known-good output per pane.

License

MIT — same as CodexBar.

Credits

CodexBar by Peter Steinberger does all the real work. This repo just paints its output onto status bars.

ai
ai-coding
api-quota
claude
codex
codexbar
dotfiles
gemini
macos
menubar
quota
ricing
sketchybar
statusline
tmux
zellij

Languages

Shell

49.7%

Rust

48.5%

Makefile

1.6%