Console touch-typing trainer with gamification
Project description
typehero
A console touch-typing trainer with gamification — think "Соло на клавиатуре" in your terminal. Work through a course of linearly-unlocked lessons, each gated on typing speed and error rate, and earn XP, levels, achievements, streaks, and combos along the way.
The trainer ships with full English and Russian courses; the typing language (a course property) and the UI language (a profile setting) are independent.
Install & run
The project is managed with uv.
uv sync # create .venv and install runtime + dev dependencies
uv run typehero # launch the TUI (equivalent to `python -m typehero`)
Your profile is stored as JSON under $XDG_CONFIG_HOME (falling back to the platform
default). A corrupt profile is backed up rather than deleted, then replaced with a fresh
one.
Development
uv run pytest # run all tests (-q is configured by default)
uv run pytest -k streak # tests matching a keyword
uv run ruff check # lint (E, F, I, UP, B, SIM)
uv run ruff format # format (100-char lines)
uv run ty check # static type check
Property-based tests use hypothesis; its database
lives in .hypothesis/.
Architecture
Dependencies flow one direction: tui → gamification → domain → engine. The inner layers never import outer ones, know nothing about the terminal, and take time as injected data — so the whole core is deterministic and unit-testable without a TUI.
| Layer | Responsibility |
|---|---|
engine/ |
Pure typing logic — keystrokes, session state, derived metrics. No I/O, no clock. |
domain/ |
Lessons, pass criteria, results, course unlocking, saved progress, generators. |
gamification/ |
XP curve, declarative achievements, calendar-day streaks, combo tracking. |
persistence/ |
Atomic JSON profile save (temp file + os.replace). |
tui/ |
The Textual layer — app, screens, widgets. |
A key convention: time and other ambient state are injected (timestamp, today),
never read from a clock inside the core. See CLAUDE.md for the full set of
codebase conventions.
Course, achievement, and i18n YAML lives under src/typehero/content/ and ships inside
the wheel.
Releases
This repository uses Conventional Commits and automated releases:
- CI (
.github/workflows/ci.yml) runsruff check,ruff format --check,ty check, andpyteston every pull request and on pushes tomain. - release-please (
.github/workflows/release-please.yml) readsfeat:/fix:commits onmain, opens a release pull request that bumps the version inpyproject.tomland updatesCHANGELOG.md, and tags a GitHub Release when that pull request is merged. - Publish (
.github/workflows/publish.yml) runs when a GitHub Release is published, builds the wheel and sdist withuv build, and uploads them to PyPI via Trusted Publishing (OIDC) — no API token is stored. The job runs in thepypienvironment. - Dependabot (
.github/dependabot.yml) proposes weekly, grouped minor/patch updates for Python dependencies (uv) and GitHub Actions, with a 7-day cooldown. Major bumps are not opened automatically.
Commit type → changelog section: feat (Features), fix (Bug Fixes), perf
(Performance), refactor (Refactoring), docs (Documentation).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file typehero-0.1.0.tar.gz.
File metadata
- Download URL: typehero-0.1.0.tar.gz
- Upload date:
- Size: 27.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
950d78b29b72ba89b4f59d12faea87e375a5c883e98ff2d5c04e1724cc655b5b
|
|
| MD5 |
ff6bb846490188e954cd8b2b5cac6138
|
|
| BLAKE2b-256 |
c545487dbe057c3f55c52def3430aea652b5e1a86b09da8f6bc3a675dcc8d0c8
|
Provenance
The following attestation bundles were made for typehero-0.1.0.tar.gz:
Publisher:
publish.yml on agolosnichenko/typehero
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
typehero-0.1.0.tar.gz -
Subject digest:
950d78b29b72ba89b4f59d12faea87e375a5c883e98ff2d5c04e1724cc655b5b - Sigstore transparency entry: 1724548145
- Sigstore integration time:
-
Permalink:
agolosnichenko/typehero@0f0e1cf7dda54171d9caa65b95a9e4522a06e3bb -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/agolosnichenko
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0f0e1cf7dda54171d9caa65b95a9e4522a06e3bb -
Trigger Event:
release
-
Statement type:
File details
Details for the file typehero-0.1.0-py3-none-any.whl.
File metadata
- Download URL: typehero-0.1.0-py3-none-any.whl
- Upload date:
- Size: 44.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c7da0a079ad2e6254186f09aeaee4ee7243f8eb97eedf6aa8c90f357193765c1
|
|
| MD5 |
62f7f32afdb48cf041e0adbc87d72f3f
|
|
| BLAKE2b-256 |
b33ccf2f6d84ddb700b0e3e68f293a59b1b8e6f0f06d00d040c27d5a19ceeb67
|
Provenance
The following attestation bundles were made for typehero-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on agolosnichenko/typehero
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
typehero-0.1.0-py3-none-any.whl -
Subject digest:
c7da0a079ad2e6254186f09aeaee4ee7243f8eb97eedf6aa8c90f357193765c1 - Sigstore transparency entry: 1724548195
- Sigstore integration time:
-
Permalink:
agolosnichenko/typehero@0f0e1cf7dda54171d9caa65b95a9e4522a06e3bb -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/agolosnichenko
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0f0e1cf7dda54171d9caa65b95a9e4522a06e3bb -
Trigger Event:
release
-
Statement type: