English | 日本語
TokenCheckerWin is a tray-resident Windows app that shows your Claude Code, OpenAI Codex, and GitHub Copilot usage from the notification area. It fetches the Claude Code / Codex 5-hour and weekly rate limits and the GitHub Copilot current-month AI Credits, and presents them in readable flyouts. When a fetch fails, it keeps showing the last successfully retrieved values.
The app stores no credentials or tokens (see Privacy). Claude Code usage is read through an unofficial endpoint, so a future change on Anthropic's side may make it stop working. Windows SmartScreen may show a warning for the unsigned build.
- Resides in the Windows notification area; per-window tray icons render a vertical % bar in code (no external image).
- Claude Code / Codex: 5-hour and weekly rate limits, time remaining until reset, per-service brand colors (Claude = blue, Codex = purple).
- Three display modes for the Claude / Codex window: Normal (detailed cards), Compact (side-by-side doughnuts), Minimum (a Nerd Font one-line status per service).
- Today's estimated spend: today's tokens from the local Claude / Codex session logs, priced with a built-in per-model table, shown in the UI language's currency — US dollars (
$N.NN (daily)) in English, Japanese yen (¥N (daily), via a public USD→JPY rate fetched once a day) in Japanese. On the Normal cards and the Minimum line; hidden when it cannot be computed. - GitHub Copilot: current-month AI Credits consumption in a dedicated window (opt-in), with today's-burn pace and a 100%-reach date estimate.
- Color escalation at 80% (amber) / 95% (red) across the icons, numbers, and bars.
- Title-bar-less rounded flyouts: drag anywhere to move,
Escto close, position remembered. - Last-successful-value fallback when a fetch fails.
- Claude Code / Codex sign-in assistance (delegated to the official CLIs).
- Light / Dark / System-linked theme and UI language (System / English / Japanese), both applied on restart.
- Auto-start at Windows sign-in.
- Windows 11
- .NET 10 SDK (
global.jsonpins10.0.100withrollForward: latestFeature) - VS Code (optional; Visual Studio is not required)
dotnet build
# Run as a tray-resident app
dotnet run --project src/TokenChecker.App
# Open a window at startup (handy for development / screenshots)
dotnet run --project src/TokenChecker.App -- --show-status # status window
dotnet run --project src/TokenChecker.App -- --show-settings # settings dialogWith no arguments, each window follows the display method chosen in settings (Always show opens at startup; Hover preview appears when you hover its tray icon). --show-status / --show-settings are case-insensitive helpers that just open the corresponding window.
To publish a self-contained single-file build:
dotnet publish src/TokenChecker.App/TokenChecker.App.csproj -c Release -r win-x64 `
--self-contained true -p:PublishSingleFile=true `
-p:IncludeNativeLibrariesForSelfExtract=true -p:EnableCompressionInSingleFile=true `
-p:DebugType=none -o publish/win-x64
.\publish\win-x64\TokenChecker.exe --show-statusSwitch from the settings dialog or the tray menu; the choice is saved to DisplayMode in settings.json (a legacy CompactMode boolean is mirrored for backward compatibility). Every mode is a rounded flyout you can drag anywhere (except links / text fields) and close with Esc.
- Normal — the most detailed layout, stacking the Claude / Codex cards. The
5husage is the hero (large number + wide bar) with the time until reset inline next to its label (e.g.2h 18m (resets 11:50));Weeklysits below with its reset datetime inline (e.g.(resets 6/17 18:00)); then today's estimated spend (¥46 (daily)), a status badge, and aShow detailslink. - Compact — two side-by-side cards showing only the
5hdoughnut, badge, and reset text. The window shrinks to the number of visible services; theLast updatedline is omitted. - Minimum — a single Nerd Font status line per service:
<icon> Claude | 5h 38% 10:50 | 7d 39% 6/17 18:00 | ¥46 (daily)(service name; the 5-hour and weekly%each with their reset time; today's spend). Text is drawn in Cascadia Mono and the icons in Symbols Nerd Font (icon runs are skipped entirely when that font is absent); the|separators are aligned between the two rows and the window auto-fits the line width. A segment is dropped when its data is unknown (e.g. no reset time, or cost not computable).
Each enabled window gets a vertical % bar icon. The Claude / Codex icon shows the maximum usedPercent of the enabled services, so the most constrained window stands out at a glance. The color follows the overall worst value: brand color (< 80%), amber (>= 80%), red (>= 95%), muted red (all providers errored), light gray (no data yet). The hover tooltip shows a per-service badge or 5h X% / Weekly Y%.
The same menu appears from any tray icon, including the control icon shown when both windows are OFF:
Refresh now— re-fetch usage (locked against duplicate refreshes).Claude/Codex status display mode▶ (Normal/Compact/Minimum).GitHub Copilot display mode▶ (Always show/Hover preview).Settings— open the settings dialog.Exit.
Sign-in / sign-out, re-checking auth, and the GitHub Copilot first-time setup / connection test live in the settings dialog, not the menu.
Badges follow the UI language (OK / Not installed / Not logged in / Auth error / Temporarily rate-limited / Fetch failed / Unknown); raw ProviderStatus names are never shown. Temporarily rate-limited means the usage endpoint itself returned HTTP 429 (not an LLM quota overage). Reset times are local: 5h shows in 2h 18m (resets 11:50), Weekly shows in 3d 4h (resets 5/27 18:00).
settings.json (under the user's AppData folder) stores app settings only: refresh interval (30 s / 1 min / 5 min / 10 min), auto-start, theme (ThemeMode), UI language (Language), DisplayMode, each window's ON/OFF and display method, the visible Claude / Codex services, the Copilot plan / custom cap, accent color, and window positions. It never stores tokens, credentials, login, URLs, paths, or email. A corrupted file falls back to defaults.
- Theme (Light / Dark / System-linked) and UI language (System / English / Japanese) are applied at startup; when you change either, the app offers to restart now (it relaunches itself cleanly) so the change takes effect.
Systemfollows the Windows color mode / display language. - An off-screen saved window position is corrected back into the visible area on open.
- Auto-start uses the
TokenCheckerWinvalue under the current user's Run key (the published exe path, or thedotnet "<app dll>"form for a dev run).
The last successful usage is retained per service, so a temporary failure of Claude or Codex does not wipe out the other's value. It is also persisted to last_usage.json so the previous value survives a restart (e.g. an HTTP 429 right after startup). On failure the badge shows the current status and the body shows Temporarily unavailable — showing the last successful values; the next success overwrites the snapshot.
GitHub Copilot moved to usage-based billing (AI Credits) on 2026-06-01. There is no real-time rate-limit window like Claude / Codex — a personal token can only retrieve the current month's AI Credits consumption. The API does not expose the monthly cap, so you supply it by selecting a plan in settings (or entering a custom value).
- Off by default (opt-in). Only when you enable "Show the GitHub Copilot window" does the app touch the GitHub billing endpoint; while disabled, the fetch never runs.
- Dedicated window showing the Copilot icon +
GitHub Copilot, the selected plan name, aCreditscaption with the estimated monthly reset (e.g.Reset ~7/1), and the usage prominently (e.g.66% used). Hovering then% usedarea (or focusing it) reveals the detail values (e.g.4,627 / 7,000 used). The window uses theMoralerspacefont if installed, otherwise Segoe UI. - Today's burn is a second hero line — the increment since 09:00 today (e.g.
✦ Today +96 (+1.4%), orToday: not measuredwith no baseline). Its spark icon escalates with the daily pace: green under 4%, amber 4–5%, red 5%+ (distinct from the monthly 80/95% thresholds). The same warning spark is overlaid on the tray icon on heavy days. Below it, the predicted 100%-reach date (e.g.At this pace, 100% around 6/21, orNot enough data to project). - Plan (None / Free=200 / Pro=1,500 / Pro+=7,000 / Max=20,000 / Custom) is chosen in settings.
Noneshows only the consumption; a plan adds the cap, remaining, fraction, and bar, escalating at 80% / 95%. (Free's code-completion and chat quotas are not in the billing endpoint and are not shown.) - Accent color for the bar's normal (< 80%) color is selectable (
Bluedefault /Green/Sky/Purple/Slate); the number andusedlabel are fixed, and the 80/95% escalation is preserved. - The reset date is a calendar-month approximation (not retrievable from the API); it can drift if your billing cycle is anchored to the signup date.
- Constraints: only usage billed directly to the personal account is in scope (Organization / Enterprise-managed usage may
403/404); accounts not on the Enhanced Billing Platform may not work. - HTTP handling:
GITHUB_TOKENunset →Not logged in;401→ invalid/expired;403→ check Plan(Read) permission, personal billing, Enhanced Billing eligibility;429→Temporarily rate-limited; 5xx / timeout / JSON anomaly →Fetch failed. No current-month consumption shows as 0 usage.
The token is read only from the GITHUB_TOKEN environment variable — never entered into the app, never stored, never printed. (In-app sign-in / OAuth / Device Flow is not implemented.) "GitHub Copilot settings" has First-time setup (a wizard) and Connection test buttons.
- Create a GitHub fine-grained PAT (name it e.g.
TokenChecker; expiration90 daysrecommended). - Under
[+ Add permissions], addPlanand selectRead-only. - Press
Generate tokenand copy it. - Set it as the Windows user environment variable
GITHUB_TOKEN(do not type it into the app), then restart TokenCheckerWin so a running instance picks it up.
The connection test never displays the token. On success it shows only usage numbers — Fetched successfully. / This month: 4,627 / 7,000 credits / Usage: 66% (or This month: 4,627 credits when the plan is None). On failure it shows only safe boilerplate (unset / invalid-or-expired / insufficient permission / rate-limited / fetch-failed). When GITHUB_TOKEN is unset and the window is ON, the window points you to "First-time setup" (no token field is placed in the window).
The app never writes tokens, OAuth credentials, full paths, or email addresses to the UI, tooltips, logs, or any saved file.
- Sign-in assistance (the Claude Code / Codex
Log in/Log outbuttons) only launches the official CLI in a newcmd.exe— it does not read~/.claude/.credentials.json,~/.codex/auth.json, the Windows Credential Manager, API keys, etc. After runningclaude/codex, pressRe-check auth status(which just re-runs the fetch). - During a usage fetch, the Claude Code provider reads the access token from
~/.claude/.credentials.json(override withCLAUDE_CONFIG_DIR) for the sole purpose of calling the unofficial usage endpoint. It is read-only: the token, credentials body, email, and paths are never displayed, saved, or logged, and the app never writes to any credential file. - For the daily-spend estimate, the app reads the local Claude / Codex session logs (
~/.claude/projects,~/.codex/sessions; override withCLAUDE_CONFIG_DIR/CODEX_HOME) read-only, extracting only token counts and model ids — never conversation content, cwd, or paths. The USD→JPY rate is fetched once a day from a free public FX API (falling back to a fixed rate on failure). Neither the rate nor the computed cost is persisted (in-memory only), so the three-file rule below is unchanged. - Diagnostics never appear in the normal view; they show only inside
Show details, and only after masking via the singleDiagnosticMasker:- email-like →
<email> - absolute paths (Windows / UNC / POSIX) →
<path> token/secret/key/authorization/bearerfollowed by:or=→name=<redacted>- JWTs (
eyJ...) →<redacted> - long alphanumeric blobs (≥ 32 chars) →
<redacted>
- email-like →
- The app writes only these three files (under
AppData, all numbers/dates only — no tokens, login, URLs, paths, or email):settings.json— app settings only.last_usage.json— numeric Claude / Codex usage only (the diagnosticMessageis nulled before writing).copilot_usage.json— GitHub Copilot delta tracking (target month, last fetch time, current-month used credits, the 09:00-today baseline); created only when the Copilot window is enabled and a fetch succeeds.
The Claude Code usage endpoint is unofficial and may change without notice — treat the displayed Claude usage as best-effort.
src/TokenChecker.Core— platform-agnostic shared library: usage models, the provider interface,UsageAggregator, and the provider implementations (Providers/).src/TokenChecker.App— WinForms +NotifyIconnotification-area app.src/TokenChecker.Poc— console POC that writes aUsageSnapshotto stdout as JSON.
TrayApplicationContext drives a timer that calls UsageAggregator.CaptureAsync(); each provider returns a ServiceUsage, and the aggregator isolates per-provider failures so one service's error never wipes out the others.
An xUnit suite under tests/ pins the app's invariants (the 80%/95% thresholds, privacy masking, the Copilot allowance, prediction logic, settings migration, provider-failure isolation, and more). Keep the whole solution green before committing or releasing.
dotnet testGitHub Actions (.github/workflows/ci.yml) runs dotnet test on windows-latest for every push / PR. A local .githooks/pre-push hook also runs dotnet test before each push and aborts on failure — enable it once per clone with git config core.hooksPath .githooks.
dotnet run --project src/TokenChecker.Poc # Claude / Codex snapshot as JSON
dotnet run --project src/TokenChecker.Poc -- --github-copilot # Copilot AI Credits only
dotnet run --project src/TokenChecker.Poc -- --github-copilot --raw # masked endpoint diagnostics- Each provider first checks whether its CLI is on the PATH; if not, it returns
NotInstalled. - Claude uses the unofficial OAuth usage endpoint.
five_hourmaps to a 300-minute window,seven_dayto 10080 minutes. HTTP401/403→Unauthorized,429→RateLimited, 5xx / timeout / JSON errors →Error. If.credentials.jsonexists but yields no usable access token (e.g. emptied by/logout), it reportsNotLoggedInrather thanError. - Codex launches
codex app-server --listen stdio://and callsinitialize→account/read→account/rateLimits/readover JSONL, then stops the app-server. A not-signed-in response isNotLoggedIn; anaccount.typeother thanchatgpt(e.g. API-key auth) reportsError, since ChatGPT sign-in is required. - Tokens, auth data, email, and full paths are never read out or printed. With
--raw, the Copilot provider tries the candidate endpoints (ai_credit/usage→usage→premium_request/usage) and prints only the HTTP status and maskedusageItemsfields — never the response body, login, or token.GITHUB_TOKENis required.
This software is distributed under the MIT License (Copyright (c) 2026 kesuhiro74). For the bundled third-party components (GitHub Octicons, the .NET runtime), see THIRD-PARTY-NOTICES.md.


