Skip to content

FlanaganSe/TypingLens

Repository files navigation

Typing Lens

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.

Privacy Model

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.

Requirements

  • 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.

Build The Mac App

Install dependencies:

pnpm install

Create 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:

  1. Open Keychain Access.
  2. Choose Certificate Assistant -> Create a Certificate.
  3. Name it TypingLens Dev.
  4. Set Identity Type to Self-Signed Root.
  5. Set Certificate Type to Code Signing.
  6. 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.sh

Run Checks

Full local validation:

pnpm validate

Package 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 test

Swift package tests do not need Input Monitoring. Only a launched .app build needs a signing identity and macOS permission.

Licenses

  • apps/mac/ and swift/: AGPL-3.0-or-later
  • packages/: MIT

See LICENSE for scope and full license texts.