Local-first writing agent for macOS.
No cloud. No upload. Just you, your data, your rules.
halen.dev
Halen is a menubar app that watches the text near your cursor and runs a set of small, focused plugins against it. Every plugin runs locally — typo correction is a static dictionary; everything else goes through your own Gemma 4 instance via Ollama. The text never leaves your Mac.
Six plugins ship with Halen out of the box. Each one is a small Swift module conforming to HalenPlugin; the marketplace dropdown lets you toggle them on/off and dive into per-plugin settings.
| Plugin | Category | What it does |
|---|---|---|
| Typo Fixer | Writing | Replaces your known typos inline as you type. Seeded with a personal dictionary of 32 frequent slips; learns new ones automatically from your edits. Backspace + retype to “undo” a bad correction — it demotes the entry forever. |
| Sentiment Guard | Writing | When you finish a sentence in any text field, Gemma 4 E4B classifies the tone against a set of rules you control (5 built-in + add your own). Hostile or irritated? Halen shows a popover asking whether to send anyway or have Gemma rephrase to your clipboard. |
| Voice Dictation | Voice | Press ⌥⌘Space anywhere. A live waveform pill follows your cursor while you speak. Apple’s on-device speech recognition transcribes locally; the text lands at the caret on stop. |
| Snippet Expander | Productivity | Type ;sig or ;today or ;summary followed by a space — Halen swaps it for static text, computed values, or a Gemma-generated rewrite of whatever you wrote above. Add your own with custom Gemma prompts. |
| Burnout Copilot | Focus | Watches three signals — time in distraction apps, recent tone trend, calendar density — and pops a “Take 10?” suggestion when 2 of 3 trip. One click creates a calendar break and triggers your Focus Shortcut. |
| Meeting Prep | Scheduling | 15 minutes before your next event, Gemma 4 reads the calendar entry and drops a 5-bullet briefing on your clipboard. A notification fires; the briefing also lives in the plugin’s recent-briefings list. |
┌────────────────────────────────────────────────────────────────┐
│ HALEN MENUBAR APP │
│ │
│ CaretObserver ──┐ │
│ (AX events) │ │
│ ▼ │
│ EventBus ──► text.pause, caret.moved, ... │
│ │ │
│ ┌──────┴──────┬──────┬──────┬──────┬──────┐ │
│ ▼ ▼ ▼ ▼ ▼ ▼ │
│ TypoFixer Sentiment Snippet Voice Burnout Meeting │
│ │ Guard Expand. Dict. Copilot Prep │
│ │ │ │ │ │ │ │
│ └─────┬───────┴──────┴──────┴───────┴──────┘ │
│ ▼ │
│ InferenceClient ──► Ollama on localhost:11434 │
│ (gemma4:e2b / e4b / 26b) │
└────────────────────────────────────────────────────────────────┘
text.pause event names line up with future method names).small → gemma4:e2b, medium → gemma4:e4b, large → gemma4:26b) — the host picks the model.Full architecture and per-plugin internals: see docs/wiki/.
Prerequisites
xcode-select --install)gemma4:e4b:
ollama pull gemma4:e4b
ollama pull gemma4:e2b # smaller / faster — used by Sentiment classification
Build and launch
git clone https://github.com/lukataylo/halen.git
cd halen
./scripts/run-dev.sh
The script builds the SPM target, wraps it in build/Halen.app, signs with your Apple Development cert (so TCC permissions persist across rebuilds), and launches.
Grant permissions
build/Halen.app to System Settings → Privacy & Security → Accessibility. Without this, no plugin can see or modify text.Everything that processes your text — typo matching, tone classification, snippet expansion, dictation — runs locally on your machine. The only network traffic Halen generates is HTTP to localhost:11434 (your local Ollama daemon). No telemetry, no analytics, no error reporting calls. The docs/wiki/privacy.md page goes through this in detail.
A scripted 1-minute demo is in docs/DEMO.md. Beat-by-beat: typo correction → sentiment popover → text expansion → meeting prep.
Sources/Halen/
├── App/ # SwiftUI App, AppCoordinator, marketplace UI, settings
├── Plugins/ # HalenPlugin protocol, PluginRegistry, HalenServices
├── Features/ # the six bundled plugins, one folder each
├── Accessibility/ # AX permission flow, caret/focused-element observer
├── Inference/ # InferenceClient protocol, Ollama HTTP client, tiers
├── Events/ # in-process EventBus + Codable event payloads
├── Overlay/ # caret-following indicator window
└── Support/ # Log, string diff, Levenshtein, windowing helpers
Resources/ # AppIcon.icns, menubar template, source SVG
docs/ # README hero, site assets, landing page, wiki
scripts/ # build-app.sh, run-dev.sh, generate-icons.swift
Apache 2.0 — same as Gemma 4. See LICENSE (coming soon).