Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ghosttype

A terminal TUI that records the exact timing of your keystrokes as you type, then lets you race a ghost replay of a past session side-by-side — like a racing-game ghost lap, but for typing rhythm.

Recording is built on a small Clock abstraction. The live TUI uses a real system clock; tests drive a VirtualClock instead, so a recorded session file is byte-for-byte reproducible given the same sequence of key events and timings.

This is an early milestone: recording, ghost playback, and a live split-pane race view are implemented.

Install

Requires Python 3.9+. curses ships with the Python standard library on macOS and Linux (Windows needs a separate curses backend, which isn't covered here).

git clone <this-repo>
cd ghosttype
pip install -e .

Usage

Start a recording session:

ghosttype record session.json

Type normally; every keystroke is captured along with its timestamp relative to the start of the recording. Press Esc to stop and write the session to session.json.

The session file is a single line of JSON:

{"duration":0.842,"events":[{"ch":"h","t":0.0},{"ch":"i","t":0.183}],"version":1}

Replay a recorded session as a ghost cursor, with each keystroke appearing at exactly the offset it was originally typed at:

ghosttype play session.json

Playback is driven by the same Clock abstraction as recording: a GhostPlayer is started against a session and, on each poll, releases every event whose recorded offset has now been reached. The live TUI polls on a real clock; tests drive a VirtualClock and advance it explicitly, so a replay's output is exactly reproducible from the same session file.

Race a ghost live: type in a split pane while a past session replays side by side, and see who finishes first.

ghosttype race session.json

The left pane ("YOU") fills in with what you type; the right pane ("GHOST") fills in on its own, at exactly the timing recorded in session.json. You "finish" once you've typed as many characters as the ghost session recorded; the ghost finishes once its last event has played. Whoever finishes first, in elapsed real time from when the race started, wins — press Esc at any point to abandon the race early. The layout and race logic (who wins, when each side finishes) are pure functions of the typed/replayed text and the clock, so they're covered by tests that never open a real terminal.

When the race ends, a score is printed alongside the result:

you win! 12.40s vs ghost's 13.10s
speed: you 42.3 wpm, ghost 40.1 wpm (+2.2 wpm)
sync: 78/100

Speed is words-per-minute (one "word" = 5 characters), compared as a straight delta against the ghost. Sync is a 0-100 score of how closely your keystroke rhythm matched the ghost's, not just your overall speed: it compares the gap between each of your consecutive keystrokes against the gap the ghost took at the same point, so typing the right characters at the wrong rhythm scores lower than matching the ghost's cadence exactly. Both numbers are pure functions of the two keystroke traces, so they're covered by tests driven off a VirtualClock with no real typing involved.

Dependencies

None beyond the Python standard library (curses, argparse, json, dataclasses). Writing a keystroke recorder and a small JSON session format is well within reach of stdlib Python, so no third-party packages are used.

Status

Built autonomously, one milestone at a time, and gated on a passing test suite before any change ships.

About

A terminal TUI that records the exact timing of your keystrokes as you type, then lets you race a ghost replay of a past session side-by-side, like a racing-game ghost lap but for typing rhythm…

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages