Metadata-Version: 2.5
Name: aium-cli
Version: 0.1.1
Summary: AI usage monitor: CLI core + GNOME Shell extension
Author-email: Jony Kalavera <mr.jony@gmail.com>
License: MIT
License-File: LICENSE
Requires-Python: >=3.14
Requires-Dist: httpx>=0.28.1
Requires-Dist: keyring>=25.7.0
Requires-Dist: pydantic-settings>=2.15.0
Requires-Dist: pydantic>=2.13.4
Requires-Dist: pyyaml>=6.0.3
Requires-Dist: rich>=15.0.0
Requires-Dist: secretstorage>=3.5.0
Requires-Dist: typer>=0.27.1
Description-Content-Type: text/markdown

# aium

AI usage monitor: a Python CLI core that polls your AI providers and a GNOME
Shell extension that displays the results. Think of it as a system monitor, but
for AI providers.

[![PyPI version](https://img.shields.io/pypi/v/aium-cli)](https://pypi.org/project/aium-cli/)
[![CI](https://github.com/jonykalavera/aium/actions/workflows/python-package.yml/badge.svg)](https://github.com/jonykalavera/aium/actions)
[![License](https://img.shields.io/github/license/jonykalavera/aium)](LICENSE)

## Features

- **Panel indicator** — robot icon with monthly spend and balance (stacked two-line label).
- **Popover** — per-provider: balance, monthly spend, rate-limit **quota windows**,
  **sparklines** (spend or quota trend), plan, and a **peak/off-peak** dot for
  providers with dynamic pricing (DeepSeek).
- **Clickable providers** — open the provider's usage/dashboard page.
- **Provider abstraction** — add a provider with one file + one registry entry.
- **Secrets** — API keys in the system keyring; OAuth providers reuse the CLI's
  own credential files (Codex, Claude Code, Antigravity).
- **History** — SQLite time-series of balances, quota and usage.
- **systemd timer** — polls every 60 minutes, no resident daemon.

## Screenshots

> TODO: add a panel/popover screenshot to `assets/screenshot.png`.

## Installation

### CLI

```bash
pipx install aium-cli     # or: uv tool install aium-cli
aium init
```

The CLI reads its config from `~/.config/aium/` (YAML) and keeps history in
`~/.local/share/aium/` (SQLite).

### GNOME Shell extension

```bash
./install.sh             # installs the CLI (uv tool), the systemd timer and the extension
```

or grab the extension zip from the [releases](../../releases) page, extract it to
`~/.local/share/gnome-shell/extensions/aium@jonykalavera/`, then enable it with
`gnome-extensions enable aium@jonykalavera` (a logout/login may be required).

## Quick start

```bash
aium providers add deepseek
aium keys set deepseek                  # prompts for the API key (keyring)
aium poll
aium status
```

## Providers

| Kind | Auth | What it reports |
|---|---|---|
| `deepseek` | API key | balance (prepaid), peak/off-peak tariff |
| `kimi` | API key | balance (prepaid) |
| `openrouter` | API key | balance + monthly usage |
| `openai` | OAuth (Codex) | rate-limit quota windows |
| `anthropic` | OAuth (Claude Code) | spend vs monthly limit + quota windows |
| `google` | OAuth (Antigravity) | plan/tier + quota (paid tiers) |
| `manual` | — | fixed subscription cost + renewal |

OAuth providers reuse the CLI's own credential files (`~/.codex/auth.json`,
`~/.claude/.credentials.json`, `~/.gemini/oauth_creds.json`) — no API key
needed. Their usage endpoints are **private/undocumented** and may break.

### Commands

```bash
aium providers add|list|show|update|remove
aium providers update deepseek --peak-window 00:30-16:30   # UTC high-tariff window
aium keys set|list|delete
aium poll                 # fetch every provider, persist history, refresh cache
aium status               # show the last cached status
aium history <id>         # balance history for a provider
```

`peak_window` marks the UTC **peak (high-tariff)** hours as `'HH:MM-HH:MM'`
(wrapping across midnight allowed); the provider row shows a peak/off-peak
indicator. DeepSeek defaults to `00:30-16:30`.

## Architecture

```
src/aium/            # Python core (config, secrets, history, polling, providers)
extension/           # GNOME Shell outlet (GJS) — reads ~/.cache/aium/status.json
  lib/               #   pure logic (unit-tested), no gi:// imports
  tests/             #   GJS unit tests (gjs -m extension/tests/run.js)
systemd/             # aium-poll timer/service (user units)
tests/               # pytest (core)
```

The extension is a **passive outlet**: no provider CRUD, no secrets. It renders
`~/.cache/aium/status.json`, whose schema (`models.py::StatusFile`) is the
contract between the core and the extension.

## Development

```bash
uv sync --all-groups --locked   # install dev deps
make uv.check                   # ruff lint + ty typecheck + format check
make uv.test                    # pytest --cov aium --blockage (network blocked)
make ext-test                   # GJS unit tests for the extension logic
```

Tools: `ruff` (lint/format), `ty` (type checker), `pytest` (coverage + network
blockage). Recipes use bare commands; prefix with `uv.` to run inside the uv
environment. To iterate on the extension on Wayland (no hot reload), use
`./scripts/dev-nested.sh` (requires `mutter-devkit`).

## License

MIT — see [LICENSE](LICENSE).
