SlopScore
00 crowd

tokitty

Claude token tracker, with a little bit of cat...
Open repo on GitHubgithub.com/nickwolf/tokitty
Python · ★ 3 · 0 forks · MIT · paperwork by the Cap'mmostly ai (inferred)light human (inferred)works-on-my-machine (inferred)other
listed 45 minutes ago by nickwolf · last checked 45 minutes ago
The owner didn't write this. This repo never submitted itself. The Cap'm found it on a truffle trawl and wrote its paperwork from what GitHub already shows. Picked by hand by the Cap'm on 2026-10-02: Claude token tracker, with a little bit of cat...; its own README says "How this was built Tokitty was built with Claude ( (Fable 5) using a subagent-driven-development workflow: an owner session designed the spe". 3 stars; MIT license. The owner did not submit this. Votes count; awards don't until the owner claims it.

I'm not calling your project slop! Geeze, it's a joke... Do you own this repo?

Log in with GitHub as nickwolf. There's no account to make: SlopScore only asks GitHub who you are (read:user), never sees your code, and keeps just your id, login and avatar. Then you can:

  • Keep it, on your terms. Commit your own slopscore.md (spec) and press Refresh. Your paperwork replaces the Cap'm's, and you can submit it for Slop of the Day.
  • Take it down. One click on Remove. It stays gone; the trawl never brings it back.

Log in with GitHub

Can't log in as the owner? Request a takedown. No login needed, and a trawled listing comes down right away.

GitHub says
Claude token tracker, with a little bit of cat...
created
2026-07-03 · pushed 12 hours ago · 285 commits · 1 contributor
release
v0.1.0 · 2026-10-01
languages
Python 100%
paperwork
licensereadme 42% health
dependencies
✓ 3 deps, none with known advisories · OSV.dev, checked 45 minutes ago

Disclosures, inferred by the Cap'm

slopbucket
vibe-coded
category
other
ai_generated
mostly
human_touch
light
status
works-on-my-machine
language (detected)
python
license (detected)
mit

The Cap'm's log

The Cap'm wrote this paperwork, not the owner. This repo never submitted itself to SlopScore. The Cap'm picked it by hand: Claude token tracker, with a little bit of cat...; its own README says "How this was built Tokitty was built with Claude ( (Fable 5) using a subagent-driven-development workflow: an owner session designed the spe". It carries the MIT license. The disclosures above are his best guess from what GitHub shows.

Is this yours? Commit a real slopscore.md and press Refresh to replace this, or remove the listing in one click. There's no account to make: you log in with GitHub.

README — the repo's own words, folded up so the grading fits on one screen

Tokitty

The tokitty window: two cat panes, each with its session and weekly usage bars and reset times The cat raising its permission flag

content working (laptop) thinking capped/flopped done hop

CI

A cat-themed desktop widget that shows your live Claude Code and Codex usage (session %, weekly %, reset countdowns, and extra-usage credits) with a pixel cat whose mood reflects how close you are to the limit. When a limit is capped, the cat rests, then stirs, then wakes up as the reset approaches, then hops back to sleep once usage clears. Does not assist with boredom and existential dread upon hitting weekly limit.

Once Tokitty has a snapshot, it keeps counting down using its own clock, no live connection needed to know when a known reset time arrives. If a poll fails (for example, the OAuth access token going stale between Claude Code sessions), Tokitty keeps showing that same cached countdown rather than blanking out, and only surfaces a small warning once the countdown should already be done and it still can't confirm the reset actually happened.

There is a burn-rate projection too. When your current pace would hit a cap before the window resets, the status line says when: session caps ~6:20 PM. It tracks whichever limit lands first, and stays blank when you are coasting.

Not affiliated with Anthropic or OpenAI (but I am open to it with either, wink wink). "Claude" and "Claude Code" are Anthropic's marks, and "Codex" and "OpenAI" are OpenAI's, used here only to describe compatibility.

Install

Download the matching archive from GitHub Releases: tokitty-<version>-windows-x64.zip for Windows, tokitty-<version>-macos-arm64.zip for Apple Silicon Macs, tokitty-<version>-macos-x86_64.zip for Intel Macs, tokitty-<version>-linux-x86_64.tar.gz for Linux. Unzip it anywhere and run Tokitty.exe, Tokitty.app, or tokitty. These builds are unsigned, so Windows and macOS block the first launch until you clear their warning; see below for each OS.

With a downloaded build, hooks (the live activity feature below) need Claude Code 2.1.139 or newer, the first version that can run a hook command without a shell. They run through a link that Tokitty repoints at itself every time it starts (current, inside its per-user state directory), so after unzipping an update or moving the folder to a new location, launch the new copy once before deleting the old one. Open Claude Code sessions keep working across that switch and nothing needs re-approving. If Tokitty can't set up the link, it says so and points hooks at the release folder directly, which means re-approving them in Codex and restarting open Claude Code sessions after every update.

Windows

SmartScreen blocks the first launch because the build is unsigned. Click More info, then Run anyway.

If your Claude Code home lives inside WSL, the common setup on Windows, its hook keeps running through WSL's own python3, not the Windows download.

macOS

Apple Silicon Macs take the macos-arm64 build, Intel Macs take macos-x86_64.

On macOS 15, Gatekeeper no longer lets Control-click ▸ Open bypass the warning. Open the app once, then go to System Settings ▸ Privacy & Security ▸ Open Anyway, or skip the dialog with xattr -dr com.apple.quarantine Tokitty.app from a terminal.

Move Tokitty to Applications before turning on Start at login or adding an account. Run straight from Downloads, it refuses and says why: macOS runs a freshly downloaded app from a random, read-only App Translocation path, so there's nowhere stable for a login item or a hook to point at.

Linux

Nothing to do on first launch. The tray icon in this build only supports X11 (xorg).

Live activity (thinking / working / permission / done)

Optional, off by default. With a downloaded build, adding an account in the Accounts dialog installs its hooks automatically, or run the app from a terminal with --install-hooks (for example Tokitty.exe --install-hooks on Windows). From source, run:

python -m tokitty --install-hooks

and the cat starts reacting to what a running Claude Code session is doing: a thinking pose while Claude is composing a response, a working pose (with the tool name) while it's mid-tool-call, a flag when Claude is waiting on you for a permission prompt, and a little done-hop when a work stretch wraps up. python -m tokitty --uninstall-hooks removes it again (the hook entries, not the copied hook script and session state files, so delete <config-dir>/tokitty/ manually if you want those gone). Existing running Claude Code sessions need to be restarted to pick up a fresh install or uninstall, since hook edits aren't hot-reloaded.

On the primary Windows+WSL2 setup, Claude Code itself lives inside WSL, not in the Windows-native ~/.claude. --install-hooks (and --uninstall-hooks) detect this automatically, using the same WSL-credentials probe the live-activity watcher uses, and target the \\wsl.localhost\<distro>\home\<user>\.claude dir instead, falling back to the Windows-local ~/.claude only if WSL resolution fails (no WSL installed, no Claude Code credentials found, etc). Running python3 -m tokitty --install-hooks from inside WSL itself installs to the same dir and is equivalent, so pick whichever shell is convenient.

Autostart

Optional, off by default. Right-click any pane (or the tray icon) and check Start at login to have tokitty launch itself automatically the next time you log in: no installer, no admin rights, nothing outside your own user account. Unchecking it removes the same registration.

The mechanism is native to each OS and needs no third-party dependency: the HKCU\Software\Microsoft\Windows\CurrentVersion\Run registry value on Windows, a LaunchAgent plist at ~/Library/LaunchAgents/com.nickwolf.tokitty.plist on macOS, and a .desktop file at ~/.config/autostart/tokitty.desktop on Linux. The checkbox reflects the real OS registration, read when tokitty starts and again after you toggle it. Nothing is cached on disk, so removing the entry by hand is picked up the next time tokitty starts. It is not picked up mid-session: remove the entry externally while tokitty is running and the checkbox keeps showing the state it read at startup until you restart. On macOS, checking the box writes the plist but doesn't load it into the running session, so the change takes effect at your next login, not immediately.

python -m tokitty --install-autostart and python -m tokitty --uninstall-autostart do the same thing from the command line, for headless setup or scripting.

If tokitty's repo clone is moved, or the Python interpreter it was registered against changes, the registration can go stale and silently fail to launch at the next login with nothing on screen to explain it. tokitty checks for this itself at every startup and rewrites the registration if it's drifted, so as long as tokitty gets launched by hand at least once from wherever it now lives, the next automatic login launch self-heals. The one thing this can't fix: deleting the whole clone with no replacement leaves a permanently broken entry, since nothing is ever running to repair it. Uncheck Start at login (or run --uninstall-autostart) before deleting a clone that has autostart enabled.

Accounts

Tokitty can track any number of Claude Code accounts side by side in one window: a pane per account instead of one, laid out in a grid once you're past four, sharing a single always-on-top card. This is opt-in and off by default. With no accounts configured, tokitty behaves exactly like v1, single account, single pane.

Right-click any pane and choose Accounts… to add, rename, or remove accounts, no config file editing needed. The dialog also lists any Claude Code installs it finds on its own (WSL-only for now) as one-click rows next to a manual "add by path" entry for anything it didn't find. Adding an account rolls it a random look; removing one only takes it out of the active list, its saved colorway and pattern stay on disk in case you add it back later. If tokitty starts with no accounts configured and finds more than one usable Claude Code install, it opens the Accounts dialog on its own instead of guessing which one you meant.

After adding or removing an account, restart tokitty to see the new pane layout, and restart any already-open Claude Code sessions to pick up the hook change (hook registration isn't hot-reloaded into a running session).

Accounts still live in accounts.json in tokitty's per-user state directory (the same directory position.json already lives in, %LOCALAPPDATA%\Tokitty\ on Windows, ~/Library/Application Support/Tokitty on macOS, $XDG_CONFIG_HOME/tokitty or ~/.config/tokitty on Linux), but the dialog is the supported way to manage it now. Each entry's config_dir points at that account's Claude Code config directory (a WSL UNC path, a native path, whatever --install-hooks would target for that account); name is an opaque identity slug the dialog assigns on add, not something meant to be typed by hand.

TOKITTY_CREDENTIALS (see Configuration below) still works, but only when no accounts are configured. If both TOKITTY_CREDENTIALS and a valid accounts.json are present, accounts.json wins and the env var is ignored; tokitty prints a startup warning to stderr so the conflict doesn't pass silently.

The resting look is normal, not an error. Work-account tokens typically expire around an hour after that account's Claude Code last ran. Outside work hours, an idle account's pane will show its last-good numbers dimmed, a sleeping cat, and a "last seen HH:MM" label. That's the expected steady state for an idle account, not a warning condition, and no error styling is applied.

Multi-account mode requires credential files. Each config_dir entry is read as <config_dir>/.credentials.json, so on macOS, where Claude Code stores credentials in the login Keychain, tokitty can't discover or add a second Keychain-backed account yet. When there's no credentials file on disk, the Accounts dialog shows a read-only "Default macOS account (Keychain)" row in place of a normal account row, since the Keychain holds one item per macOS user with no per-account identity to key on.

Setting TOKITTY_DEBUG_ACCOUNTS=2 renders a fake two-pane card (one normal, one in the resting look) without needing any real accounts configured, handy for checking layout changes.

Per-model usage

The bars described so far come from Claude Code's usage endpoint, which only answers for a subscription. If you pay per token with an API key, that endpoint has nothing to tell you, and tokitty used to sit on "can't find credentials" forever.

There is a second view that reads Claude Code's own transcripts instead, under <config-dir>/projects/, and totals the tokens each model used. It needs no network, no credentials, and no subscription. Right-click a pane and pick View ▸ Per-model to switch, or View ▸ Limits to go back. If tokitty finds transcripts and no credentials at all, it selects the per-model view for you once on first run, and leaves it as an ordinary setting you can change afterwards.

Each row is one model, with the tail folded into an other (N) row so what's on screen always adds up to the real total. Usage window ▸ picks the last 24 hours, the last 7 days, or the current calendar month; switching between them is instant, because the scanner keeps a month of records in memory and re-totals them. Usage readout ▸ switches the figures between dollars and token counts. On a subscription those dollars are what the same work would have cost at API rates rather than anything you are billed, which is why the line says so, and why the token readout is the more honest one to leave it on.

Set a budget from Set budget… and the bars change meaning: instead of each model's share of the window, they become a share of the budget, and the usual green/amber/red comes back with something real to measure against. Budgets are per account and per window, so $40 for a month and $40 for a day are different settings, and a blank entry clears one.

Two details worth knowing, because both make the totals differ from a naive reading of the same files. A turn that made several API calls records each one separately, and the top-level total for that turn leaves out advisor calls, so tokitty adds up the individual calls and bills advisor calls against the model that actually ran them. The same message also gets rewritten several times inside one transcript, 4,037 of 5,817 entries on the machine this was built on, so only the last copy of each is counted.

Prices live in tokitty/prices.json, one section per provider, each stamped with the pricing page it came from and the date it was read. A model that isn't in it still has its tokens counted and shown, but its cost reads -- and the total is marked >= rather than quietly pretending to be complete. Once any rate on screen is more than 60 days old, the status line says "at old API rates" instead of "at API rates".

To price a model before the next release, put a prices.json of the same shape in Tokitty's state directory (%LOCALAPPDATA%\Tokitty, ~/Library/Application Support/Tokitty, or ~/.config/tokitty). Its models replace the packaged ones entry by entry. An entry that only gives rates keeps the packaged long-context pricing for that model; set "short_context_only": false to make a model flat on purpose. A malformed override is ignored with a warning on stderr and in --debug-print, and the packaged prices stay in effect.

{"schema": 1, "providers": {"mine": {"as_of": "2026-09-23", "models": {
  "gpt-7": {"input": 2.0, "output": 10.0, "cache_read": 0.2, "cache_write_5m": 2.5, "cache_write_1h": null}
}}}}

python3 scripts/refresh_prices.py rewrites the packaged file from the live Anthropic and OpenAI pricing pages and prints what was added, changed, and kept; --check only reports. It refuses to write if a page's columns no longer line up with its rates.

python -m tokitty --debug-print prints the same breakdown per account as text, which is the first thing to look at if a number looks wrong.

Checking usage from an agent

--debug-print needs no display and exits when it's done, so a coding agent can run it in the middle of a task and read its own limits. For each account it prints a session: and a weekly: line, each with the percentage used and the reset time in UTC, followed by the per-model breakdown above.

I have Claude Code run python3 -m tokitty --debug-print at natural checkpoints in long sessions, before dispatching a subagent or starting a long build. When the weekly figure gets close to 100% it stops starting new work, commits what's finished, and writes down where it got to. Before this, sessions and their subagents would hit the limit mid-change and leave uncommitted edits behind. Each run makes one usage request per account, the same one the widget makes on every poll.

Codex

A pane can track an OpenAI Codex account instead of a Claude Code one. It gets the same limit bars (whichever windows your plan has) and the same Per-model view, both read from the rollout files Codex writes under <codex-home>/sessions/ and archived_sessions/. Nothing is fetched and no credentials are read, so a Codex pane works offline.

Add one from the Accounts dialog: pick Codex as the harness, click Add by path…, and enter the Codex home (C:\Users\<you>\.codex on Windows, ~/.codex elsewhere). Pointing it at the sessions folder inside works too. If your own Codex home has rollouts and isn't an account yet, the dialog lists it as a one-click row. Tokitty installs no hooks for a Codex account, and --install-hooks skips it, so nothing is ever written inside the Codex home.

You can still add one by hand. The entry in accounts.json needs "provider": "codex" and config_dir pointing at the Codex home:

{"name": "codex", "config_dir": "C:\\Users\\you\\.codex", "provider": "codex"}

Entries without a provider key are Claude Code accounts, so existing files keep working unchanged. An entry naming a provider this build doesn't know gets a pane that says so instead of numbers. When a window holds more than one harness, each pane's label gets a tag like codex·nibbles so you can tell them apart.

A few things behave differently from a Claude Code pane:

  • Codex only records its rate limits when it takes a turn, so between sessions the bars are a snapshot. Past 10 minutes old, the status line says when it was taken ("as of 4:12 PM"), and the countdowns keep running on tokitty's own clock as usual.
  • There are no thinking or working poses, because Codex has no hook for tokitty to listen to.
  • Costs use OpenAI's standard-tier API rates. Fast mode bills double and Batch and Flex half, but the rollouts don't say which tier a turn ran on.
  • codex-auto-review, the automatic review pass, isn't on OpenAI's pricing page. Its tokens are counted and shown, but its cost reads -- and the total is marked >=.
  • Requests to models that OpenAI prices by context length (currently gpt-5.6-sol, gpt-5.5, and gpt-5.4 over 272K input tokens) are costed separately, and show up as a long row where a long-context rate is published.

Customization

A cat's look is two independent axes: a colorway (its tone palette) times a pattern (which tone each body region takes). Right-click a pane to change either. Colorway ▸ is a radio submenu of six (orange, gray, black, white, cream, brown) and Pattern ▸ is a radio submenu of nine (solid, tabby, bicolor, tabby_white, calico, tuxedo, socks, colorpoint, van). Picking either applies immediately and persists, so six colorways × nine patterns give 54 built-in looks. colorpoint and van pale the body toward the colorway's light tone, so they read best on the lighter colorways.

All six colorways down, all nine patterns across

Colorways run top to bottom in menu order, patterns left to right.

Two ways to let tokitty pick for you: Randomize rolls a fresh colorway + pattern for that pane and saves it, and Surprise me (a checkbox) re-rolls every pane to a new look on each launch. Surprise me is off by default, so your chosen look sticks. Both only ever roll from the built-in colorways and patterns, never free-form colors.

Customize… opens a small dialog with a color-chooser button per overridable piece (coat base, coat shading, card background, bar color); each pick live-previews on the pane right away, and Reset to preset clears all four overrides back to the current colorway + pattern's stock colors.

Every choice you make is saved to customization.json, in the same per-user state directory as position.json (see Accounts above for the exact path per OS), and reloaded on the next launch. In single-account mode the file has one entry keyed "default"; with accounts configured it's keyed by each account's identity slug, so each pane keeps its own look and colors independently. It stores colorway + pattern; older files that stored a single coat name are migrated automatically on load. accounts.json's coat field (see above) is only ever a seed for the legacy single-coat shape; it sets the look the first time a pane appears with no stored customization yet, and has no effect once a look is saved.

Each pane also gets a label under the sprite. Right-click a pane and choose Rename… to set one; it's saved to customization.json and persists across restarts. A pane with no name set shows no label, matching how single-account mode has always worked. Clearing the name back to empty in the dialog reverts to no label. The Accounts dialog's own account list shows a generic placeholder ("Cat 1", "Cat 2", and so on) for any account that hasn't been renamed yet, just for that list; it doesn't change what's shown on the pane itself.

With no accounts.json and no customization.json, tokitty runs as a single pane and, on first launch, rolls one random look and saves it, so a fresh install gets its own cat that then stays put across restarts, rather than always starting orange tabby.

Transparency

Right-click a pane and pick a level from Transparency ▸ (100%, 90%, 80%, 70%, 60%, 50%). It applies immediately and is saved to settings.json, so it survives a restart. The setting is app-wide, not per pane.

On Windows only the card background fades: the cat and the usage bars stay fully opaque at every level. That takes two stacked windows, one holding the faded background and one holding the sprites and bars with its background color keyed out, so anything you set the card to shows the desktop through it while the cat stays readable. Everywhere else it is a single window at that alpha, which fades the cat and the bars along with the background. On X11 with no compositor running, nothing happens at all and no error is raised.

50% is the floor on purpose. Keyed-out pixels are click-through, so a card faded all the way out would be both invisible and unclickable, leaving the optional tray icon as the only way back.

Two things override the level you picked. A pending permission prompt forces the window back to fully opaque until you answer it, since a dimmed "Claude is waiting on you" defeats the point; with several panes, one waiting pane makes all of them opaque. And in Customize…, picking exactly #010203 for a color gets one unit of blue added when that color is painted, because that is the pixel value Windows punches out. Your saved color is left as you chose it, only the painted pixel differs.

Security & privacy

Tokitty only reads your local Claude Code OAuth credentials file: it never writes to it, never touches the refresh token, and never transmits the access token anywhere except in a single request to api.anthropic.com. Window position, your per-pane look/color/label choices, and three app-wide settings (position.json, customization.json, and settings.json, the latter holding "show tray icon", "surprise me" and the transparency level) are the only things Tokitty's core (non-live-activity) code persists, and all live in your OS's normal per-user config directory, never inside this repo. customization.json only ever contains built-in colorway/pattern names, #rrggbb hex strings, and label text you chose yourself through the right-click menu. Autostart's on/off state is not among them: it lives entirely in the OS's own registration (a registry value, a LaunchAgent plist, or a desktop entry, depending on platform) and never in settings.json, so there is no stored copy to fall out of step with what the OS will actually do at your next login.

The live-activity feature above is opt-in and changes this picture only if you turn it on:

  • --install-hooks registers a small hook script in each configured Claude Code config dir's settings.json (merged additively into any existing hooks, with a timestamped backup of settings.json taken first) and copies the hook script itself to <config-dir>/tokitty/hook_writer.py. It's idempotent, so re-running it skips events already installed, and every entry it adds is tagged so --uninstall-hooks can remove exactly tokitty's entries and nothing else.
  • Claude Code invokes that script once per hook event (UserPromptSubmit, PreToolUse, PostToolUse, Notification, Stop, SubagentStop, SessionEnd) with that event's full JSON payload on stdin, which for PreToolUse includes the tool's input arguments. The script only reads that payload to decide what to write. It doesn't read prompts, file contents, or transcripts from anywhere else.
  • Per session, it writes one small JSON state file to <config-dir>/tokitty/sessions/<session_id>.json containing just the session id, the event name, a sequence number, a timestamp, and, for tool-call and agent events, the tool name and agent id. Prompt text, tool arguments/output, and file contents are never written to that file. On SessionEnd the file is deleted; tokitty's own watcher also deletes state files it judges stale (no update within its timeout window) so a crashed or killed session doesn't leave the cat stuck.
  • The hook script never writes to stdout and never exits non-zero, under any input. Claude Code treats hook stdout/exit code as live control signals (e.g. a non-zero exit can block the tool call), so the script is wrapped so nothing it does can ever interfere with your actual session. This is covered by tests, not just a claim.
  • None of this activity data is transmitted anywhere; it's read locally by tokitty's own watcher to drive the sprite.

On macOS the credentials are read from the login Keychain instead of a file. Tokitty's access stays read-only there too: it never writes to the item and never touches the refresh token. One thing worth knowing before you click Always Allow: macOS Keychain ACLs are per-binary, and the binary being authorized is /usr/bin/security. So granting it persistent access means any process running as you can afterwards read that token by shelling out to security, without a prompt. That is a property of how Keychain authorization works, not something tokitty can tighten. A narrower grant would require tokitty to be a signed app bundle with a stable identity rather than a Python script.

Choosing Allow instead of Always Allow grants a single read, and while the token stays valid tokitty's cache means that's roughly one prompt per token lifetime. But the cache is invalidated the moment the token expires, deliberately, since that's how tokitty notices Claude Code has refreshed it. So once nothing is refreshing the token (the idle-account resting look above, e.g. outside work hours), every retry on the 30s to 600s backoff is a cache miss and re-prompts: on the order of fifty prompts overnight, not one. If you leave tokitty running unattended, use Always Allow.

The per-model view reads more than the credentials file: it opens the .jsonl transcripts under <config-dir>/projects/ to count tokens. It reads only each entry's usage numbers, model id, and timestamp. Prompt text, tool arguments, tool output, and file contents are never read out of those files, never persisted, and never transmitted; the totals are computed in memory and drawn on the pane. Nothing about this view contacts the network at all, which is the point of it. Your budget figures live in settings.json alongside the other app-wide settings.

A Codex account (see Codex) is read-only in the same way and narrower: tokitty reads the rollout files under that Codex home's sessions/ and archived_sessions/, never its auth.json or any other credentials, writes nothing there, and makes no network request for it.

Multi-account mode (above) extends this picture the same way single-account mode already worked, just once per configured account: tokitty reads OAuth credentials and (if hooks are installed) hook/session state from each account's Claude Code config dir. Nothing about what's read, persisted, or transmitted changes. It's the same read-only credentials access, the same opt-in hook installation, and the same locally-scoped session-state files, just applied per account instead of once. accounts.json itself only ever contains an identity slug, a config-dir path, and the harness kind per account, all assigned by the Accounts dialog, not typed in by hand.

Platforms tested

  • Windows 11 + WSL2 (native Python via pythonw.exe, Claude Code running inside WSL2): the primary, recommended setup, verified end-to-end by hand. The full pipeline (credential resolution, WSL fallback, live API polling, mood/wake-sequence logic, rendering) runs against a real account, and the window itself (drag, always-on-top, sizing, text legibility, animation) is visually confirmed on a real desktop.

  • Linux, macOS, Windows, automated (CI badge above): the full test suite runs on all three, on Python 3.10 and 3.14, for every change, and the real Tk window is booted headlessly on Linux (under xvfb) to confirm it constructs. So the shared logic (credential resolution, WSL-path handling, mood/wake sequencing, layout and sprite rendering) and, on Linux, GUI construction are covered wherever the badge is green.

  • macOS 15 (Apple silicon, python.org Python 3.14 + Tk 9.0), hands-on, with caveats: credential resolution from the login Keychain, live API polling against a real account, and the window itself (drag, always-on-top, right-click menu, Refresh now) confirmed by hand on 2026-08-04. The denial path was exercised for real: deny the Keychain prompt, get the dimmed card with a recovery hint, then recover via Refresh now without restarting. Two caveats, both tracked:

    • There is no tray icon on macOS. The tray is disabled there automatically, whatever tray_enabled is set to, and the "Show tray icon" menu entry is hidden. pystray's darwin backend needs NSApplication.run() on the main thread, and Tk's mainloop() already owns it, so starting a tray aborts the process rather than failing gracefully (#45). Nothing is lost from the menu: every action, Refresh now included, is on the window's right-click menu. A native menu-bar item would be the real fix (#44 touches the same main-thread question).
    • The system menu bar stays. Removing it needs a real .app bundle with LSUIElement=1; no runtime call can do it, because Tk owns and rebuilds that menu (#44).

    One path is covered by tests but not by hand: a Keychain denial that happens after a successful poll, where a cached snapshot is already on screen. Reproducing it needs an expired access token, so it was not practical to trigger live.

  • Not yet hands-on: interactive desktop use on native Linux (real-account polling and live window behaviour). The shared code paths are covered above, so it should work, but nobody has run it there interactively yet.

Runnin

Read the rest on GitHub

Scan report · 2026-10-02
  • ✓ Prohibited terms or links
  • ✓ Repository eligibility
  • ✓ slopscore.md paperwork
  • ✓ Content policy
  • ✓ Risk review

From the balcony · 0 of 3 clapped

    Cap'm Slop, Princess and Crusoe read it and passed. Their reasons are on the balcony, with every other verdict.

    Critics are accounts on this site with no GitHub account behind them. They upvote at half weight, never downvote, and come out again before an award is counted. Who they are.

    0 comments

    log in to comment.

    report this listing — log in to report