No description
Find a file
Björn Wittmann 1b9754b4bb
All checks were successful
CI / test (push) Successful in 26s
Release / build-and-upload (release) Successful in 8s
Merge pull request 'fix: align peak hours with Z.ai weekday-only rules and credit rates' (#13) from fix/peak-hours-weekday-rules into main
Reviewed-on: #13
2026-08-15 10:45:12 +02:00
.forgejo/workflows fix: add TAG env to verify step (was step-scoped, assertion would fail) 2026-06-28 19:39:14 +00:00
assets fix: autostart desktop entry never launches on KDE Plasma 2026-07-21 18:39:44 +02:00
docs Added screenshot of popup window 2026-06-28 19:53:42 +02:00
src/zai_tray_checker fix: correct wrapping-window countdown after midnight, add wrap tests 2026-08-15 08:39:57 +00:00
tests fix: correct wrapping-window countdown after midnight, add wrap tests 2026-08-15 08:39:57 +00:00
.gitattributes fix: simplify .gitattributes 2026-06-28 14:32:22 +00:00
.gitignore feat: initial Z.AI Tray Checker implementation 2026-06-28 14:31:34 +00:00
LICENSE feat: initial Z.AI Tray Checker implementation 2026-06-28 14:31:34 +00:00
pyproject.toml feat: release pipeline + dynamic version from git tag 2026-06-28 18:36:57 +00:00
README.md fix: align peak hours with Z.ai weekday-only rules and credit rates 2026-08-15 08:15:18 +00:00

Z.AI Tray Checker

A KDE Plasma system tray tool for monitoring Z.AI GLM Coding Plan usage.

Sits in your system tray and shows you — at a glance — how much of your 5-hour and weekly quota you've used, and warns you when you're in the more expensive peak hours.

Features

  • 🔑 Multiple keys — track several named API keys at once; each gets its own quota bars
  • 📊 5-hour quota bar — percentage used in the rolling 5-hour window, with reset countdown
  • 📈 Weekly quota bar — percentage used in the weekly window, with reset countdown
  • 🏷️ Plan level badge — shows your subscription tier (PRO, LITE, MAX) per key
  • ⚠️ Peak hours warning — highlights when you're in the weekday 14:0018:00 UTC+8 peak window (standard credit rate; off-peak is 50%)
  • 🎨 System theme aware — follows your KDE light/dark color scheme automatically
  • 🔐 Secure key storage — API keys stored in KDE Wallet via the Secret Service API, never in plaintext
  • 🔄 Auto-refresh — updates every 2 minutes (configurable), with a live countdown to the next refresh
  • 🖱️ Click to expand — click the tray icon for a popup panel near the tray, click outside to dismiss

Screenshots

Z.AI Tray Checker Popup

Requirements

  • Python 3.10+
  • KDE Plasma (or any desktop with a system tray + Secret Service provider)
  • A Z.AI API key from z.ai/apikeys

System packages (Fedora KDE)

sudo dnf install python3-pyside6 python3-keyring python3-keyring-kwallet

Installation

Download the latest .whl from the releases page and install:

pip install --user zai_tray_checker-*.whl

From source

git clone https://git.kagaku.eu/TeamAI/zai-tray-checker.git
cd zai-tray-checker
pip install --user .

Check the installed version:

zai-tray-checker --version

Autostart on login

Install the desktop file into your autostart directory, substituting the absolute path of the executable:

mkdir -p ~/.config/autostart
ZTC_PATH="$(command -v zai-tray-checker)" || { echo "zai-tray-checker not found on PATH"; exit 1; }
sed "s|^Exec=.*|Exec=$ZTC_PATH|" \
    assets/zai-tray-checker.desktop > ~/.config/autostart/zai-tray-checker.desktop

The absolute path matters: on KDE Plasma, autostart entries are launched by systemd-xdg-autostart-generator, which resolves Exec= against the systemd user manager's PATH — that does not include ~/.local/bin, so a bare Exec=zai-tray-checker is silently skipped at login.

Or use the systemd user unit:

mkdir -p ~/.config/systemd/user
cp assets/zai-tray-checker.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now zai-tray-checker

Usage

  1. Launch: Run zai-tray-checker or log in (if autostart is set up).
  2. Add API keys: On first launch, the Manage API Keys dialog opens. Add one or more keys, each with a name you'll recognise (e.g. Work, Personal). Keys are stored securely in KDE Wallet.
  3. Click the tray icon to see the usage panel — one section per key, with a shared peak-hours banner and "last updated" footer.
  4. Right-click for menu options: refresh, manage API keys, quit.

Managing keys

Open Manage API Keys… from the tray menu. The table lists each key by name (the key value itself is masked). Use Add, Edit, and Delete to maintain your keys. A single legacy key from an older version is migrated automatically to a key named Default.

Tray icon colors

With multiple keys, the tray icon reflects your best (healthiest) key — the one with the most remaining quota — so a single healthy key keeps the icon calm. The state is derived from that key's worst window (5-hour or weekly):

Icon color Meaning
🔵 Blue usage < 70%
🟡 Amber usage 7090%
🔴 Red usage ≥ 90%, or all keys errored
🟣 Purple quota exhausted (≥ 100%)

Hovering the tray icon shows a tooltip with one line per key, prefixed by its name, plus a single peak-hours line when active.

Notifications

The app shows desktop notifications for:

  • Threshold crossings — when 5-hour or weekly quota crosses 70%, 90%, or 100%
  • Peak hours — when peak hours start (standard credit rate) and end (50% off-peak rate)

Notifications fire only on transitions (not on every refresh), and reset when usage drops back below the threshold.

Peak hours

Z.ai charges credits at the standard rate (1×) during peak hours — Monday to Friday, 14:0018:00 UTC+8. At all other times, including weekends all day, usage is charged at 50% of the standard rate (see the Plan Update Announcement).

The tray panel shows a banner indicating whether you're currently in peak hours and when the status will change.

Configuration

Settings are stored in ~/.config/zai-tray-checker/settings.json:

{
  "refresh_interval_seconds": 120,
  "peak_start_hour": 14,
  "peak_end_hour": 18,
  "peak_timezone_offset": 8,
  "notify_thresholds": true,
  "notify_peak_changes": true
}

Key names (and a random id per key) are stored in ~/.config/zai-tray-checker/keys.json. The API key secrets are never stored in either file — they live in the system keyring (KDE Wallet), one entry per key.

Development

# Clone and install in dev mode
git clone https://git.kagaku.eu/TeamAI/zai-tray-checker.git
cd zai-tray-checker
pip install -e ".[dev]"

# Run tests
pytest

# Run the app
python -m zai_tray_checker.main

Project structure

zai-tray-checker/
├── src/zai_tray_checker/
│   ├── __init__.py          # Package init
│   ├── api_client.py        # Z.AI Monitor API client
│   ├── config.py            # Settings persistence
│   ├── credentials.py       # Keyring (KDE Wallet) integration
│   ├── peak_hours.py        # Peak hours detection logic
│   ├── main.py              # Tray icon + popup panel GUI
│   └── assets/              # SVG tray icons (bundled in package)
├── assets/
│   └── zai-tray-checker.desktop  # Autostart entry
├── tests/
│   ├── test_api_client.py   # API client tests
│   ├── test_config.py       # Settings tests
│   ├── test_gui_imports.py  # GUI import smoke tests
│   └── test_peak_hours.py   # Peak hours logic tests
├── .forgejo/workflows/
│   └── ci.yml               # CI: runs pytest on every push/PR
├── pyproject.toml
└── LICENSE

API reference

This tool uses the Z.ai Monitor API:

Endpoint Purpose
GET /api/monitor/usage/quota/limit Returns all quota limits (5-hour, weekly, MCP) with percentages and reset times

The API returns an array of limit objects:

{
  "limits": [
    {"type": "TOKENS_LIMIT", "number": 5, "percentage": 25, "nextResetTime": 1782677318619},
    {"type": "TOKENS_LIMIT", "number": 1, "percentage": 5, "nextResetTime": 1783259354990},
    {"type": "TIME_LIMIT", "number": 1, "percentage": 0, "nextResetTime": 1785246554994}
  ],
  "level": "pro"
}
  • TOKENS_LIMIT with number=5 → 5-hour rolling window
  • TOKENS_LIMIT with number=1 → weekly window
  • TIME_LIMIT entries are currently ignored (MCP tool usage)

Authentication: the API key is sent as a bare token in the Authorization header.

License

MIT — see LICENSE.