Native SwiftUI menu-bar app: global hotkey → capture selected text (AX API / clipboard fallback) → grammar (Harper) / local AI (MLX) → replace in place. Free/paid entitlement gate + Lemon Squeezy device-cap licensing, $0 marginal cost per user. Heavyweight engines behind protocol stubs so it builds out of the box. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
GrammaGem (macOS app)
A private, on-device writing assistant for macOS — a one-time-purchase replacement for Grammarly. Fix grammar, sharpen tone, and rewrite anything in any app via a global hotkey. Your words never leave your Mac.
Built in public. The grammar core is open-source; the repo is permissively licensed. We sell the signed, notarized, auto-updating build + a multi-device license + support — not code secrecy.
Architecture (two layers)
GrammaGem (native menu-bar app, Swift/SwiftUI)
├─ System integration global hotkey → capture selected text (AX API /
│ clipboard fallback) → route to engine → replace in place
├─ Layer 1: GRAMMAR Harper (Rust, Apache-2.0) — spelling/grammar/punctuation,
│ deterministic, <10ms, offline. Powers live underlines. FREE.
├─ Layer 2: AI MLX (Apple Silicon) + a small instruct model — rewrite,
│ tone, "Ask", translate, Mode rewriting. Closes the gap. PAID.
└─ Entitlements + Licensing free/paid gate · device-cap activation (Lemon Squeezy)
Network is touched only for: first-run model download (Hugging Face), license activate/validate (Lemon Squeezy), and update checks (Sparkle/GitHub Releases). Writing never requires internet. No telemetry.
Repo layout
mac/
├─ Package.swift SwiftPM executable (Apple-frameworks only → builds out of the box)
├─ Sources/GrammaGem/
│ ├─ App/ @main app, menu bar, onboarding, settings, Ask popover, AppState
│ ├─ System/ hotkey (Carbon), AX capture/replace + clipboard fallback, app detection, permissions
│ ├─ Grammar/ GrammarEngine protocol + Harper stub + personal dictionary
│ ├─ AI/ AIEngine protocol + MLX stub + model manager + Writing Modes
│ ├─ Licensing/ Lemon Squeezy client, device fingerprint, Keychain, license manager
│ ├─ Entitlements/ free/paid gate + daily AI counter
│ └─ Core/ config, models, logging
├─ Tests/GrammaGemTests/ unit tests (entitlements, Harper rules, fingerprint, modes)
├─ Resources/Modes/ Mode prompt presets (paid ones tuned in release only)
├─ AppSupport/ Info.plist (LSUIElement) + entitlements
├─ scripts/ build → sign/notarize → release(Sparkle/GitHub)
└─ harper-ffi/ Rust↔Swift FFI for the real Harper core (placeholder)
Build & run
cd mac
swift build # compiles the app (Apple frameworks only)
swift test # runs the unit tests
swift run GrammaGem # runs as a menu-bar (accessory) app
# Package a .app bundle you can double-click:
./scripts/build.sh # → dist/GrammaGem.app
On first launch, grant Accessibility when prompted (System Settings → Privacy & Security → Accessibility). Without it the app degrades gracefully to a manual paste-in window. Default hotkeys: ⌘; fix selection, ⌘' Ask.
Prefer Xcode? Open
Package.swiftdirectly in Xcode 26 (File → Open). For a production app target, point it atAppSupport/Info.plist+ entitlements.
What's real vs. stubbed
This codebase implements the full architecture and product logic end-to-end,
with the heavyweight native integrations behind clean protocol seams so it
compiles with zero external dependencies. Search TODO(real-integration).
| Area | Status |
|---|---|
| System-wide capture → transform → replace loop | ✅ Real (AX + clipboard fallback, CGEvent ⌘C/⌘V, restore clipboard) |
| Global hotkeys | ✅ Real (Carbon RegisterEventHotKey) |
| Active-app detection + Mode mapping | ✅ Real (NSWorkspace) |
| Permissions onboarding | ✅ Real (AXIsProcessTrusted, deep-links, auto-advance) |
| Entitlements gate + daily AI counter (resets local midnight) | ✅ Real |
| Device fingerprint (IOPlatformUUID → SHA-256) | ✅ Real (IOKit + CryptoKit) |
| Keychain license storage | ✅ Real (Security framework) |
| Lemon Squeezy activate/validate/deactivate + hard-verify + offline grace | ✅ Real client (needs your store/product/variant IDs) |
| Personal dictionary (25 free / unlimited paid) | ✅ Real |
| Menu bar UI, Settings, Ask popover | ✅ Real (SwiftUI) |
| Harper grammar core | 🔌 Stub: small pure-Swift rule set; swap for the Rust FFI (harper-ffi/) |
| MLX local LLM | 🔌 Stub: deterministic transforms; swap for mlx-swift + downloaded model |
| Model download | 🔌 Stub: simulated progress; swap for real Hugging Face streaming |
| KeyboardShortcuts recorder UI / Sparkle auto-update | 🔌 Documented seams (scripts + Package.swift comments) |
Before shipping
- Set real IDs in
Core/AppConfig.swift: Lemon SqueezyexpectedStoreID/expectedProductID/ per-tiervariantID(set each variant's activation limit to the device cap: Solo 1 / Personal 2 / Studio 4),bundleIdentifier,supportEmail, model portal URL. - Replace the Harper stub with the FFI (
harper-ffi/README.md). - Replace the MLX stub + model manager with
mlx-swiftand real HF download. - Add
KeyboardShortcuts+SparkleSwiftPM deps (commented inPackage.swift). - Codesign + notarize via
scripts/sign-notarize.sh(needs Apple Developer Program).
Honest gaps (by design)
- No plagiarism detection. It needs a server-side corpus + live index, which breaks both the $0-cost rule and the privacy promise. Out of scope, not faked.
- The gate is intentionally soft. Because the code is public, a technical user could compile a build with the gate removed — that's the VoiceInk model and it's fine. The product is the signed build + license + support, not secrecy.
Cost model — $0 marginal cost per customer
| Item | Cost |
|---|---|
| Server / database | $0 (none exists) |
| AI inference (on device) | $0 |
| Model hosting (Hugging Face) | $0 |
| Update hosting (GitHub Releases) | $0 |
| License validation (Lemon Squeezy) | $0 (included) |
| Apple Developer Program | $99 / year (fixed) |
| Payment processor | ~5% + fee per sale |
License
Permissive (MIT/Apache-2.0) to maximize trust and stars. Monetization is the signed binary + multi-device license, not the source.