Shows how many flashcards are waiting, in your Omarchy bar. Click it for a
panel of today's study stats; right-click to open Anki. It reads 0 when the
queue is clear rather than disappearing, so a cleared queue never looks the
same as a broken widget.
It works whether or not Anki is running. The widget reads collection.anki2
directly (read-only) instead of talking to AnkiConnect, which only answers
while Anki is open — precisely when you don't need reminding.
omarchy plugin add https://github.com/jcr-byte/omarchy-anki.git --enablePlugins run unsandboxed inside your omarchy-shell process, so read the source
first. There isn't much of it: a manifest, two QML files, and one Python
script.
Update with omarchy plugin update jcr-byte.anki, remove with
omarchy plugin remove jcr-byte.anki.
Set these on the widget's entry in ~/.config/omarchy/shell.json:
{ "id": "jcr-byte.anki", "includeNew": true, "refreshInterval": 300000 }| Setting | Default | Meaning |
|---|---|---|
includeNew |
true |
Count unseen new cards in the total |
refreshInterval |
300000 |
Poll interval, milliseconds |
launchCommand |
the bundled anki-open |
What right-click runs |
Left click opens the stats panel, right click opens Anki, middle click forces a refresh. Hover for the breakdown without opening anything.
Left-clicking the pill opens a popup with three sections:
- Today — answers, distinct cards, time spent and seconds per answer, the
new/review/relearn split, and how many answers were
Again. - True retention — the share of cards answered in the review state that
passed, split into mature (interval ≥ 21 days) and young, with today's rate
next to a 30-day rate for context. Learning and relearning answers are
excluded, since drilling a card until it sticks says nothing about whether it
was remembered. Each rate carries its
passed/total, because a percentage off four answers is noise and only the denominator shows it. - Remaining — the due, learning and new counts the pill adds up.
The panel is a view over the same poll the pill uses; opening it costs no extra read of the collection.
It is also reachable from a keybind:
omarchy-shell jcr-byte.anki toggle # the stats panel
omarchy-shell jcr-byte.anki study # launch Anki
omarchy-shell jcr-byte.anki refresh # re-read nowRight-click runs the bundled anki-open. It focuses the window whose class is
exactly anki and starts Anki only when there is none, and it leaves a
starting instance alone -- Anki takes seconds to map its window, and a second
click in that gap would otherwise race a second copy for the collection lock
and lose both.
It deliberately does not use omarchy-launch-or-focus, which matches its
pattern against class or title and takes the first hit: any window with
"anki" in its title -- an AnkiWeb tab, a terminal sitting in this plugin's
directory -- gets focused ahead of Anki itself.
Both halves are arguments, anki-open [window-class] [launch-command], which
is what flatpak users need -- a different window class as well as a different
command:
{ "id": "jcr-byte.anki", "launchCommand": "~/.config/omarchy/plugins/jcr-byte.anki/anki-open net.ankiweb.Anki 'flatpak run net.ankiweb.Anki'" }The guard that spots a starting instance looks for a process named anki; set
ANKI_PROCESS if yours is named something else.
The count is capped by each deck's daily new/review limits, the same as Anki's
own screen. An uncapped count sits at the size of the backlog and never reaches
zero on a day the work is finished — a pill that reads 48 when Anki says
0 new is worse than no pill.
Those limits live in deck_config.config as a protobuf blob. The helper reads
two integers out of it by field number rather than pulling in Anki's generated
bindings. Field numbers are not a stable interface, so every parse failure
falls back to the raw uncapped counts instead of guessing; the JSON reports
which path ran as "limited": true|false.
Counts are rolled up per top-level deck tree and its preset applied once, which matches Anki whenever a tree shares one preset. Learning cards are never capped — Anki shows those past the daily limits too.
- Anki with collection schema 18 — every release from 2.1.50 (2022) through 26.x. Other schemas hide the widget rather than risk a wrong number.
python3(already present on Arch).
Collections are found at ~/.local/share/Anki2 or
~/.var/app/net.ankiweb.Anki/data/Anki2 (flatpak), using the User 1 profile
or else the first profile holding a collection. Override with
ANKI_COLLECTION=/path/to/collection.anki2.
It hides only when the collection can't be read or the schema isn't 18 — an
empty queue shows 0. To tell which, run the helper by hand:
~/.config/omarchy/plugins/jcr-byte.anki/anki-dueIt prints one line of JSON — counts, or an error explaining itself. A
"stale": true line means the collection was momentarily unreadable and the
last known counts are being shown; the widget dims itself when that happens.
- Never writes to your collection: opened
mode=rowithpragma query_only. - Polling creates
collection.anki2-shm/-walbeside the collection. Standard SQLite WAL files that Anki itself makes and cleans up. - Day boundaries follow your Anki rollover hour (
config.rollover), not midnight, matching Anki's owntiming_today. The day number and the rollover do not line up: a collection created at noon with a 4am rollover starts day N sixteen hours aftercrt + N * 86400, so both the count and the "today" window are taken from the rollover itself.
MIT