No description
  • Python 47.8%
  • QML 46.9%
  • Shell 5.1%
  • Makefile 0.2%
Find a file
2026-09-24 21:11:41 +01:00
backend add claude 2026-09-24 21:11:41 +01:00
contents add claude 2026-09-24 21:11:41 +01:00
tests add claude 2026-09-24 21:11:41 +01:00
updater feat: add detailed updates tab 2026-08-03 12:46:16 +01:00
.gitignore add claude 2026-09-24 21:11:41 +01:00
build-release.sh chore: establish local project baseline 2026-08-03 12:24:35 +01:00
install.sh add claude 2026-09-24 21:11:41 +01:00
Makefile chore: establish local project baseline 2026-08-03 12:24:35 +01:00
metadata.json soften tab divider styling 2026-08-03 12:51:16 +01:00
README.md add claude 2026-09-24 21:11:41 +01:00
uninstall.sh add claude 2026-09-24 21:11:41 +01:00

AI Quota Plasma widget

Plasma 6 taskbar widget showing provider quota pages for Codex, OpenCode Go, and Claude Code.

Features

  • Compact view: one chip per provider, with independently selected quota windows and one provider icon.
  • Popup: isolated, horizontally swipeable Codex, OpenCode Go, and Claude Code pages behind icon-only tabs (names in tooltips).
  • Every provider page shows all available quota windows in a responsive vertical list.
  • Inline switches show or hide each individual quota window in the taskbar.
  • Codex page shows optional 5-hour and weekly windows, reset countdowns, account email, plan type, and refresh.
  • OpenCode Go page scrapes live rolling, weekly, and monthly dashboard windows.
  • Claude Code page shows 5-hour session and weekly limits, reset countdowns, plan type, and (popup only) cloud credit balance and extra usage status.
  • Refresh on load, every 15 minutes, when the popup opens (if data is over a minute old), or with Refresh button on live providers.
  • Weekly pace card on Codex and Claude Code pages compares usage against elapsed window time.
  • Updates tab shows installed/latest versions, last check time, status, and verified install action.
  • Provider descriptors and reusable pages support future adapters.
  • No third-party Python dependencies. No credentials are stored by this project.

Requirements

  • KDE Plasma 6 (targeted and tested against Plasma 6.7 APIs)
  • Python 3.10+
  • codex CLI with app-server support
  • user systemd
  • kpackagetool6
  • JetBrainsMono Nerd Font for update glyphs

Codex must already be authenticated. Backend calls codex app-server --stdio, sends initialize, then reads account/read and account/rateLimits/read.

Claude Code must already be logged in with a Pro or Max subscription. Backend reads the OAuth access token from ~/.claude/.credentials.json at refresh time, sends it only to https://api.anthropic.com/api/oauth/usage, and never refreshes, writes, returns, or logs it.

OpenCode Go uses the existing dashboard session entry in ~/.pi/agent/auth.json:

{
  "quota-status": {
    "opencode-go": {
      "workspaceId": "...",
      "authCookie": "..."
    }
  }
}

The backend reads this file at refresh time, sends the cookie only to https://opencode.ai/workspace/<workspaceId>/go, and never returns or logs either credential.

Install

Do not run this script as root. It installs widget package and backend under user-local paths, then starts a user service.

./install.sh

Add AI Quota to panel through Plasma widget chooser. Backend listens only on 127.0.0.1:17934.

Automatic updates

Installation enables quota-widget-update.timer. It checks daily with up to one hour of randomized delay.

Updater downloads:

  • https://apache.tsbprodesk.co.uk/files/programs/quota-widget-latest.tar.gz
  • https://apache.tsbprodesk.co.uk/files/programs/hashes/quota-widget-latest.tar.gz.sha256

Release archive may contain project files directly or inside one top-level directory. It must contain metadata.json, install.sh, and app ID org.kde.plasma.quota. Increment KPlugin.Version using MAJOR.MINOR.PATCH for every release.

Generate both upload-ready files from repository root:

./build-release.sh

Outputs mirror server paths:

dist/programs/quota-widget-latest.tar.gz
dist/programs/hashes/quota-widget-latest.tar.gz.sha256

Updater verifies SHA-256, rejects unsafe archive paths and downgrades, then runs release install.sh. Check manually or inspect logs:

quota-widget-update
systemctl --user status quota-widget-update.timer
journalctl --user -u quota-widget-update.service

SHA-256 protects transfer integrity but does not protect against compromise of server hosting both archive and checksum.

Uninstall

./uninstall.sh

Uninstall removes widget, backend, updater, wrappers, user services, timer, and updater state. It does not modify Codex login state or files.

Backend contract

GET http://127.0.0.1:17934/v1/quota?provider=codex returns one JSON document:

{
  "provider": "codex",
  "ok": true,
  "updatedAt": 1700000000,
  "account": {"email": "user@example.test", "planType": "pro"},
  "quota": {
    "id": "weekly",
    "label": "Weekly",
    "available": true,
    "usedPercent": 20,
    "remainingPercent": 80,
    "windowDurationMins": 10080,
    "resetsAt": 1700600000
  },
  "quotas": [
    {
      "id": "fiveHour",
      "label": "5-Hour",
      "available": true,
      "usedPercent": 10,
      "remainingPercent": 90,
      "windowDurationMins": 300,
      "resetsAt": 1700018000
    },
    {
      "id": "weekly",
      "label": "Weekly",
      "available": true,
      "usedPercent": 20,
      "remainingPercent": 80,
      "windowDurationMins": 10080,
      "resetsAt": 1700600000
    }
  ],
  "error": null
}

Codex keeps quota as weekly compatibility alias. Missing windows remain unavailable rather than receiving inferred usage values.

GET http://127.0.0.1:17934/v1/quota?provider=opencode-go returns a quotas array containing rolling, weekly, and monthly windows with remaining percentages and reset timestamps.

GET http://127.0.0.1:17934/v1/quota?provider=claude returns a quotas array containing session (5-hour) and weekly windows.

Updates tab sends POST /v1/update with internal request header, then polls GET /v1/update/status. Status includes installed version, latest checked version, and last successful check time. Backend starts quota-widget-update.service; downloaded releases retain existing SHA-256 verification.

Errors keep the same shape with ok: false and {code, message}. Backend never emits subprocess stderr, dashboard HTML, auth cookies, workspace IDs, or protocol payloads. Unknown routes return 404. HTTP server binds loopback only.

Development

make test
make check

Tests use static protocol-shaped messages; they never access real account data.

Limitations

  • OpenCode Go scraping depends on its server-rendered hydration field names (rollingUsage, weeklyUsage, and monthlyUsage). Dashboard changes may require parser updates.
  • OpenCode Go dashboard cookies expire; refresh credentials in ~/.pi/agent/auth.json when the widget reports an invalid session.
  • Reset countdowns depend on Codex supplying windowDurationMins and resetsAt. 5-hour and weekly selection uses duration, not primary/secondary position.
  • Claude Code usage uses an undocumented OAuth endpoint and may change. Expired tokens are not refreshed by the backend; run claude once to refresh them.
  • Service uses fixed local port 17934; change port in install script, service template, and QML endpoint together if port conflicts.
  • Existing installed widget with same ID is replaced by kpackagetool6 during install.

Credits

OpenCode Go dashboard request and hydration-field discovery were informed by @mjfuertesf/pi-quota-status. This widget uses its own Python adapter and normalized multi-window response.