Add README.md
This commit is contained in:
@@ -0,0 +1,209 @@
|
|||||||
|
# keydr
|
||||||
|
|
||||||
|
A terminal typing tutor with adaptive learning, a skill-tree progression
|
||||||
|
system, and live statistics — built in Rust on [ratatui]. Heavily inspired by
|
||||||
|
[keybr.com], extended for code practice and the terminal.
|
||||||
|
|
||||||
|
Warning: still very much a WIP and is heavily vibe-coded so there may be bugs.
|
||||||
|
Backwards compatibility is not guaranteed in this phase of development.
|
||||||
|
|
||||||
|
## What makes it different
|
||||||
|
|
||||||
|
Most TUI typing apps either drop you on a fixed word list or randomize from a
|
||||||
|
dictionary. keydr keeps a model of _your_ typing: per-key timing, per-bigram
|
||||||
|
error rates, and a confidence score for every key on the keyboard. The text it
|
||||||
|
generates for you is shaped by that model — words bias toward the keys you're
|
||||||
|
slowest at, new keys unlock only when the keys you already have are solid, and
|
||||||
|
the difficulty grows with you.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
### Adaptive engine
|
||||||
|
|
||||||
|
- **Per-key confidence model.** Every keystroke updates an exponential moving
|
||||||
|
average of your per-key time. Your `confidence` for a key is your target
|
||||||
|
speed divided by that filtered time — a key with `confidence >= 1.0` is at
|
||||||
|
or above your target speed.
|
||||||
|
- **Gradual letter unlocking.** You start with 6 letters in English-frequency
|
||||||
|
order (`e t a o i n …`). A new letter unlocks only when every letter you
|
||||||
|
already have is confident, so you're never thrown into the full alphabet at
|
||||||
|
once.
|
||||||
|
- **Focused-key biasing.** Whichever included key has the lowest confidence
|
||||||
|
becomes your "focused" key. The generator searches its Markov chain for
|
||||||
|
states containing the focused letter and starts pseudo-words from there, so
|
||||||
|
drills naturally pile up practice on your weak spots.
|
||||||
|
- **Phonetic pseudo-word generation.** Words are generated from a Markov
|
||||||
|
transition table (the same approach as keybr) so they're pronounceable and
|
||||||
|
language-shaped, not random consonant noise.
|
||||||
|
- **N-gram error tracking.** Beyond single keys, keydr tracks bigrams and
|
||||||
|
trigrams with Laplace-smoothed error rates and a redundancy formula that
|
||||||
|
separates _genuine_ transition difficulties (e.g. awkward same-finger
|
||||||
|
bigrams) from errors that are just proxies for a single weak key. Hard
|
||||||
|
bigrams get folded into drill selection.
|
||||||
|
|
||||||
|
### Skill tree
|
||||||
|
|
||||||
|
Once you've mastered the lowercase alphabet, you don't just keep grinding
|
||||||
|
prose — five sibling branches unlock at once and you pick what to drill next:
|
||||||
|
|
||||||
|
- **Capitals** (A–Z, 3 levels) — sentence-start and proper-noun rules
|
||||||
|
- **Numbers** (0–9, 2 levels)
|
||||||
|
- **Prose punctuation** (`. , ' " ? !` …, 3 levels)
|
||||||
|
- **Whitespace** (Tab, Enter, …, 2 levels)
|
||||||
|
- **Code symbols** (`{ } [ ] ( ) ; : = + - * /` …, 4 levels)
|
||||||
|
|
||||||
|
Each branch tracks its own current level and its own focused key. You can have
|
||||||
|
multiple branches "in progress" at once, and drills can be scoped globally
|
||||||
|
(everything you've unlocked) or to a single branch.
|
||||||
|
|
||||||
|
### Three drill modes
|
||||||
|
|
||||||
|
- **Adaptive** — the default. Generated text from the phonetic model, biased
|
||||||
|
by your skill-tree scope and focused key.
|
||||||
|
- **Code** — language-specific syntax practice. Bundled snippets for Rust,
|
||||||
|
Python, JavaScript, and Go, with optional opt-in downloads of real code
|
||||||
|
samples from GitHub for more variety. Configurable per-language, with an
|
||||||
|
onboarding screen on first use and a download progress screen.
|
||||||
|
- **Passage** — type real prose from public-domain books (Project
|
||||||
|
Gutenberg). Opt-in downloads, configurable paragraphs-per-book limit, falls
|
||||||
|
back to bundled content when offline.
|
||||||
|
|
||||||
|
### Statistics dashboard
|
||||||
|
|
||||||
|
A multi-tab dashboard with everything the engine has learned about you:
|
||||||
|
|
||||||
|
- **Dashboard** — current WPM, accuracy, confident-key count, level/streak
|
||||||
|
- **History** — recent drills with WPM/accuracy
|
||||||
|
- **Activity** — a GitHub-style heatmap of drilling activity over time
|
||||||
|
- **Accuracy** — per-key accuracy heatmap laid out on the keyboard
|
||||||
|
- **Timing** — per-key timing heatmap
|
||||||
|
- **N-grams** — your worst bigrams/trigrams, redundancy scores, watchlist of
|
||||||
|
emerging weak transitions, and what's currently driving drill focus
|
||||||
|
|
||||||
|
### Visual keyboard
|
||||||
|
|
||||||
|
A live keyboard diagram colors each key by the finger that should press it,
|
||||||
|
highlights your focused key, and (in terminals that support the Kitty keyboard
|
||||||
|
protocol) lights up modifier keys as you press them. A separate **Keyboard
|
||||||
|
Explorer** screen lets you click around the layout to inspect any key's
|
||||||
|
stats.
|
||||||
|
|
||||||
|
### Theming
|
||||||
|
|
||||||
|
14 built-in themes: Catppuccin (Mocha/Latte), Dracula, Gruvbox (Dark/Darkest),
|
||||||
|
Kanagawa (Wave/Dragon/Lotus), Nord, One Dark, Solarized Dark, Tokyo Night,
|
||||||
|
Farout, plus an ANSI-safe `terminal-default` that respects your terminal's
|
||||||
|
own colors.
|
||||||
|
|
||||||
|
### Internationalization
|
||||||
|
|
||||||
|
- **UI translated into 21 languages** (`en`, `de`, `es`, `fr`, `it`, `pt`,
|
||||||
|
`nl`, `sv`, `da`, `nb`, `fi`, `pl`, `cs`, `ro`, `hr`, `hu`, `lt`, `lv`,
|
||||||
|
`sl`, `et`, `tr`).
|
||||||
|
- **Dictionaries for the same 21 languages**, sourced from
|
||||||
|
[keybr-content-words](https://github.com/aradzie/keybr.com).
|
||||||
|
- **Keyboard layout profiles**: QWERTY, Dvorak, Colemak, German QWERTZ,
|
||||||
|
French AZERTY — with per-layout finger maps so the diagram stays accurate.
|
||||||
|
- Unicode-normalized (NFC) input matching, so composed and decomposed forms
|
||||||
|
of accented characters compare equal.
|
||||||
|
|
||||||
|
### Import / export
|
||||||
|
|
||||||
|
Back up everything — config, profile, key stats, ranked stats, drill history
|
||||||
|
— to a single timestamped JSON file from the Settings page, and restore it on
|
||||||
|
another machine. Machine-local paths (download directories) are preserved
|
||||||
|
from the target machine on import. Versioned format with a clear error if
|
||||||
|
schemas don't match.
|
||||||
|
|
||||||
|
### Other niceties
|
||||||
|
|
||||||
|
- Atomic JSON writes (temp file → fsync → rename) so a crash mid-save can't
|
||||||
|
corrupt your stats.
|
||||||
|
- Auto-continue between drills with a brief input lock so a trailing
|
||||||
|
keystroke doesn't start the next drill prematurely.
|
||||||
|
- Mouse support for menus, tabs, and the keyboard explorer.
|
||||||
|
|
||||||
|
## Build and run
|
||||||
|
|
||||||
|
keydr is a regular Cargo project. You need a recent Rust toolchain (Rust
|
||||||
|
edition 2024, i.e. a 2026-era stable compiler).
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git clone <repo-url> keydr
|
||||||
|
cd keydr
|
||||||
|
cargo run --release
|
||||||
|
```
|
||||||
|
|
||||||
|
Or build once and run the binary:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cargo build --release
|
||||||
|
./target/release/keydr
|
||||||
|
```
|
||||||
|
|
||||||
|
### CLI flags
|
||||||
|
|
||||||
|
```sh
|
||||||
|
keydr [--theme <name>] [--layout <layout>] [--words <n>]
|
||||||
|
```
|
||||||
|
|
||||||
|
- `--theme, -t` — pick a theme by name for this run (e.g. `dracula`,
|
||||||
|
`nord`, `catppuccin-mocha`)
|
||||||
|
- `--layout, -l` — pick a keyboard layout: `qwerty`, `dvorak`, `colemak`,
|
||||||
|
`de_qwertz`, `fr_azerty`
|
||||||
|
- `--words, -w` — number of words per drill
|
||||||
|
|
||||||
|
Everything else is set from inside the app, on the Settings screen.
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
The `network` Cargo feature (on by default) pulls in `reqwest` and enables the
|
||||||
|
optional GitHub code download and Project Gutenberg passage download flows. To
|
||||||
|
build a fully offline binary:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cargo build --release --no-default-features
|
||||||
|
```
|
||||||
|
|
||||||
|
### Files on disk
|
||||||
|
|
||||||
|
- Config: `~/.config/keydr/config.toml`
|
||||||
|
- Profile, key stats, drill history: `~/.local/share/keydr/*.json`
|
||||||
|
- Downloaded passages: `~/.local/share/keydr/passages/`
|
||||||
|
- Downloaded code samples: `~/.local/share/keydr/code/`
|
||||||
|
|
||||||
|
(`dirs` is used to resolve these, so the exact paths follow XDG/macOS/Windows
|
||||||
|
conventions on your platform.)
|
||||||
|
|
||||||
|
### Tests and benchmarks
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cargo test
|
||||||
|
cargo bench # n-gram benchmarks in benches/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Terminal requirements
|
||||||
|
|
||||||
|
keydr works in any reasonably modern terminal. For the best experience —
|
||||||
|
modifier-key highlighting on the keyboard diagram, unambiguous key
|
||||||
|
disambiguation, and per-key release events — use a terminal that supports the
|
||||||
|
[Kitty keyboard protocol] (Kitty, WezTerm, foot, recent Ghostty, recent
|
||||||
|
Alacritty). keydr falls back gracefully on terminals that don't (tmux, mosh,
|
||||||
|
SSH to older hosts) using timer-based heuristics.
|
||||||
|
|
||||||
|
A true-color terminal is recommended so the bundled themes render as
|
||||||
|
intended; the `terminal-default` theme is provided for ANSI-only setups.
|
||||||
|
|
||||||
|
## License and attribution
|
||||||
|
|
||||||
|
keydr is licensed under the GNU Affero General Public License v3.0 only
|
||||||
|
(AGPL-3.0-only) — see [LICENSE](LICENSE).
|
||||||
|
|
||||||
|
It incorporates content and ideas from [keybr.com] (dictionaries, the core
|
||||||
|
adaptive algorithm). See [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md) for
|
||||||
|
attribution and [docs/license-compliance.md](docs/license-compliance.md) for
|
||||||
|
the compliance process.
|
||||||
|
|
||||||
|
[ratatui]: https://ratatui.rs/
|
||||||
|
[keybr.com]: https://www.keybr.com/
|
||||||
|
[Kitty keyboard protocol]: https://sw.kovidgoyal.net/kitty/keyboard-protocol/
|
||||||
Reference in New Issue
Block a user