An AI-powered CLI typing trainer with personalized error analysis, built with React Ink and Google Gemini AI.
- Real-time Typing Tests - Practice typing with instant visual feedback
- AI-Powered Analysis - Get personalized insights about your typing patterns using Google Gemini AI
- Adaptive Practice Mode - Focus on characters you struggle with most
- Progress Tracking - Track your WPM, accuracy, and improvement over time
- Persistent Statistics - Your progress is saved locally between sessions
- Node.js 18.0.0 or higher
- npm or yarn
# Clone the repository
git clone git@github.com:trett/taip-trainer.git
cd taip-trainer
# Install dependencies
npm install
# Run the application
npm startTo enable AI-powered error analysis with Google Gemini:
- Get a free API key from Google AI Studio
- Set the environment variable:
# Temporary (current session)
export GEMINI_API_KEY="your_api_key_here"
# Permanent (add to your shell config)
echo 'export GEMINI_API_KEY="your_api_key_here"' >> ~/.zshrc
source ~/.zshrcnpm startUse arrow keys to navigate menus and the following keys:
| Key | Action |
|---|---|
| ↑/↓ | Navigate menu options |
| Enter | Select option |
| ESC | Go back / Exit |
| R | Retry test (from results) |
| S | View statistics (from results) |
| A | AI Analysis (from results) |
- Start New Test - Begin a typing test with random text
- Practice Weak Characters - Practice with text targeting your problem areas
- View Statistics - See your overall progress and trends
- Exit - Quit the application
- Characters turn green when typed correctly
- Characters turn red when typed incorrectly
- Current position is highlighted in blue
- Live statistics show WPM, accuracy, errors, and time
- Visual progress bar shows completion status
- View your final WPM, accuracy, and error count
- Press R to retry with new text
- Press S to view your statistics
- Press A for AI-powered error analysis
- Press ESC to return to main menu
When you press A after a test, Gemini AI analyzes your errors and provides:
- Error Patterns - Which characters you frequently mistype
- Likely Causes - Why you might be making these mistakes
- Practice Exercises - Custom sentences targeting your weak areas
- Improvement Tips - Actionable advice for better typing
Your profile and statistics are stored in:
~/.typing-trainer/profile.json
- Total tests completed
- Average WPM and accuracy
- Problem characters with error counts
- Last 20 test session history
- AI-generated practice texts
taip-trainer/
├── index.tsx # Entry point
├── package.json # Dependencies and scripts
├── README.md # This file
└── src/
├── App.tsx # Main application component
├── api/
│ └── gemini.js # Google Gemini AI integration
├── components/
│ ├── Menu.tsx # Main menu
│ ├── TypingTest.tsx # Core typing interface
│ ├── PracticeMode.tsx # Adaptive practice
│ ├── Results.tsx # Test results display
│ ├── Statistics.tsx # Progress statistics
│ ├── ErrorAnalysis.tsx # AI analysis display
│ └── ProgressBar.tsx # Visual progress components
└── utils/
├── stats.js # WPM/accuracy calculations
├── storage.js # Profile persistence
├── textGenerator.js # Sample texts
└── analyzer.js # Error pattern detection
- React - UI library
- Ink - React for CLI
- Google Generative AI - Gemini AI SDK
- tsx - TypeScript/JSX execution
WPM Calculation:
WPM = (characters / 5) / (seconds / 60)
Accuracy Calculation:
Accuracy = ((total - errors) / total) * 100
npm start # Run the application
npm run dev # Run with watch mode (auto-restart on changes)This error occurs when running in a non-interactive terminal. Make sure you're running in a proper terminal emulator, not through automation or piped input.
This means the Gemini API key is not set or there was an API error. Check:
GEMINI_API_KEYenvironment variable is set- API key is valid
- Network connection is available
Ensure the application has write permissions to your home directory. The profile is stored at ~/.typing-trainer/profile.json.
Contributions are welcome! Please feel free to submit issues and pull requests.
MIT License
- Powered by Google Gemini AI
- Built with Ink by Vadim Demedes
