Metadata-Version: 2.4
Name: typefaster-cli
Version: 0.1.1
Summary: A terminal-first typing game inspired by MonkeyType and TypeRacer.
Project-URL: Homepage, https://github.com/Anoshor/typefaster-cli
Project-URL: Repository, https://github.com/Anoshor/typefaster-cli
Author: Anoshor Paul
License: MIT
License-File: LICENSE
Keywords: cli,game,monkeytype,terminal,tui,typeracer,typing,wpm
Classifier: Environment :: Console
Classifier: Intended Audience :: End Users/Desktop
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Games/Entertainment
Requires-Python: >=3.11
Requires-Dist: httpx>=0.27
Requires-Dist: platformdirs>=4.2
Requires-Dist: rich>=13.7
Requires-Dist: textual>=0.60
Requires-Dist: typer>=0.12
Requires-Dist: websockets>=12.0
Provides-Extra: dev
Requires-Dist: black>=24.0; extra == 'dev'
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Requires-Dist: textual-dev>=1.5; extra == 'dev'
Description-Content-Type: text/markdown

# ⌨ TYPEFASTER-CLI

[![CI](https://github.com/Anoshor/typefaster-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/Anoshor/typefaster-cli/actions/workflows/ci.yml)
[![Python](https://img.shields.io/badge/python-3.11%2B-blue)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)

A **terminal-first** typing game inspired by MonkeyType and TypeRacer.

> Not a web app. Not a browser game. Not a desktop GUI.
> A polished **Python terminal application** that works offline first, then scales to internet multiplayer.

```bash
typefaster
```

…and you're racing within seconds. No login, no server, no Docker, no internet required.

---

## What Phase 1 delivers

- **Instant offline races** — random quote, live WPM / accuracy / progress / timer.
- **30 / 60 / 120 second** race modes.
- **Ghost races** against your `personal-best`, `last`, or a `random` historical run, animated live.
- **Local profile & stats** in SQLite — races played/won, best/avg WPM, best/avg accuracy, total chars, total time, full history.
- **Daily challenge** — same quote for everyone each day, with a local daily leaderboard.
- **Polished TUI** built on **Textual** + **Rich**, keyboard-only, resize-aware.

## Planned CLI

```bash
typefaster                                   # launch straight into the game
typefaster race --time 60 --ghost personal-best
typefaster race --ghost last
typefaster race --ghost random
typefaster daily
typefaster profile
typefaster stats
typefaster history
```

---

## Tech stack

**Client (Phase 1):** Python 3.11+, Typer, Rich, Textual, SQLite (stdlib), platformdirs.
**Server (Phase 2):** FastAPI, asyncio, WebSockets, Pydantic, Redis, Docker Compose.

## Repository layout

```
typefaster-cli/
├── client/typefaster/   # CLI app: domain · services · infra · ui · net · assets
├── server/app/          # FastAPI server: routers · ws · repositories · security
├── shared/              # shared schemas, WS protocol, scoring, anti-cheat
├── infra/               # redis.conf · nginx.conf (TLS + WS proxy)
├── docs/                # architecture, schemas, protocol, deployment, roadmap
├── tests/               # client unit · integration · UI smoke
├── scripts/             # quote dataset tooling
├── docker-compose.yml   # redis + server (+ nginx via --profile proxy)
├── pyproject.toml · Makefile · README.md
```

See [`docs/architecture.md`](docs/architecture.md) for the full design.

## Online play (Phase 2)

Run the server stack (Redis + FastAPI + WebSockets) with Docker:

```bash
cp .env.example .env       # set TYPEFASTER_JWT_SECRET
make up                    # redis + server on :8000  (make up-proxy adds nginx TLS)
```

Then, from the client:

```bash
typefaster register alice          # create an account
typefaster login alice
typefaster lobby create --name "Friday Sprint" --time 60
typefaster lobby join ABC123       # join a friend's private lobby
typefaster lobby list              # browse public lobbies
typefaster leaderboard global      # global | daily | weekly
typefaster logout
```

The server is **authoritative**: it controls race start/finish, re-scores every
result, and runs anti-cheat before writing leaderboards. See the docs:

- [API specification](docs/api-spec.md)
- [WebSocket protocol](docs/websocket-protocol.md)
- [Redis schema](docs/redis-schema.md)
- [Deployment guide (single Linux VM)](docs/deployment.md)

The client points at `http://localhost:8000` by default; set `server_url` in
`~/.config/typefaster/auth.json` to target a deployed server.

## Development

```bash
make install   # editable install + dev deps
make play      # launch the game
make test      # pytest
make lint      # ruff
make typecheck # mypy
make format    # black + ruff --fix
make check     # lint + typecheck + test (CI parity)
```

> **Note on the monorepo layout:** the importable package lives at
> `client/typefaster`. A normal install (`pip install .`, used by Docker and end
> users) places it on the path automatically. For local development the
> `Makefile` exports `PYTHONPATH=client`, so `make play` / `make test` always
> work. If you invoke tools directly, prefix with `PYTHONPATH=client` (e.g.
> `PYTHONPATH=client python -m typefaster`).

## Design preferences locked for Phase 1

- **Quotes:** curated public-domain set, tagged `short` / `medium` / `long` for difficulty buckets and 30/60/120s fit.
- **Backspace:** allowed (MonkeyType-style) — corrections permitted, original errors still count toward accuracy; exposed as a Settings toggle.

## License

MIT.
