Typing Lens is a private typing coach for macOS. It is built for developers and writers who are interested in improving their typing accuracy and performance.
The product:
- real typing should inform practice;
- raw typing should not be stored;
- speed only matters when accuracy and correction cost hold;
- practice only counts when it transfers to text that was not just drilled.
The public browser demo is live at https://typing-lens.pages.dev/. The Mac app is the full product: it builds a local profile from aggregate evidence and uses that profile to prescribe short, targeted practice.
See docs/dogfood.md, docs/architecture.md, and docs/roadmap.md for the
current cohort and distribution gates.
Stored locally:
- short pattern keys such as supported bigrams/trigrams or coarse metric keys;
- aggregate timing summaries, rates, sample sizes, confidence, and fact IDs;
- bounded numeric history for trends and practice summaries.
Never stored:
- Raw typed passages or replayable keystroke streams;
- Prompt text, passage text, or typed attempts from practice;
- Clipboard contents, URLs, window titles, or document titles;
- Bridge payload logs or AI prompts containing raw typing.
The app excludes sensitive app categories before aggregation, respects Secure Event Input, has a visible paused/recording state, and can export or purge the local SQLite database.
- macOS 14+
- US-QWERTY primary layout for capture-oriented use
- Xcode with Swift 6
- Node.js 22+
- pnpm 10
This repo uses SwiftPM and pnpm workspaces. There is no tracked .xcodeproj.
Install dependencies:
pnpm installCreate one stable local code-signing identity. This matters because macOS TCC binds Input Monitoring grants to the app's code signature. Ad-hoc signing gives each rebuild a new identity, so capture can silently fail even when System Settings still appears to grant permission.
One local setup path:
- Open Keychain Access.
- Choose Certificate Assistant -> Create a Certificate.
- Name it
TypingLens Dev. - Set Identity Type to
Self-Signed Root. - Set Certificate Type to
Code Signing. - Add it to your shell:
export TYPING_LENS_CODESIGN_IDENTITY="TypingLens Dev"Build and launch:
# Builds the web coach, builds the Swift app, assembles `build/Typing Lens.app`,
# signs it with your identity, quits any running copy, and opens the new bundle.
scripts/build-mac-app.sh --launch# Reset Input Monitoring, rebuild, and relaunch if capture stops after a signing change:
scripts/build-mac-app.sh --reset-input-monitoring --launch# Remove local app data:
tccutil reset ListenEvent dev.typin.TypingLens
rm -rf "build/Typing Lens.app" ~/Library/Application\ Support/TypingLens# For non-capture work only, ad-hoc signing is available behind an explicit opt-in:
TYPING_LENS_ALLOW_ADHOC_TCC=1 scripts/build-mac-app.shFull local validation:
pnpm validatePackage examples:
swift test --package-path swift/Packages/Store
swift test --package-path apps/mac
pnpm -F @typing-lens/site test
pnpm -F @typing-lens/web-coach testSwift package tests do not need Input Monitoring. Only a launched .app build
needs a signing identity and macOS permission.
apps/mac/andswift/: AGPL-3.0-or-laterpackages/: MIT
See LICENSE for scope and full license texts.