A macOS app that looks at your screen and answers questions about it — out loud.
Hold O, speak, let go. It captures your screen, sends it with your question, and reads the answer back as it streams. There is no text box.
Built as a single Swift file with no dependencies. ~900 lines, AppKit, no package manager.
./build.sh # → ~/Desktop/supermode.app
./build.sh /path/to/out.app # or somewhere elseNeeds Xcode command line tools. Nothing else.
On first run, approve Screen Recording, Microphone and Speech Recognition, then quit and reopen — macOS only hands a new grant to a fresh process.
The app is ad-hoc signed, so every rebuild produces a new code hash and macOS treats it as a different app. Those three permissions have to be re-approved after each build. A real Developer ID certificate is what makes grants survive rebuilds.
| Hold O | record a question; release to send |
| ⌘E | expand the last answer (sends no screenshot, so it's the fastest request) |
| ⌘K | new thread — clears context, which is also a speed control |
| ⌘P | edit the system prompt |
Paste a Gemini or OpenAI key in the top bar. Keys are stored in ~/.omi_supermode_key_*
and never leave your machine except to that provider.
Measured on a real screen capture, median of 3 trials, time to first visible token:
| configuration | first token |
|---|---|
Turbo — gemini-flash-lite-latest @ 900px |
925 ms |
Normal — gemini-flash-latest @ 1280px |
1632 ms |
| text-only question, no screenshot | 790 ms round trip |
Seven things get it there:
- Streaming. SSE via
:streamGenerateContent?alt=sse, rendered per delta. The reply header is drawn on the first non-empty delta so nothing sits empty. - Thinking turned down.
generationConfig.thinkingConfig.thinkingLevel = "low". Note the nesting — puttingthinkingLevelone level higher returns a 400, and a retry will hide it while silently costing a round trip on every send. - Right-sized captures. Downscaled in-process through ImageIO — no subprocess, no second trip to disk. Turbo sends 79 KB where the first version sent 260 KB.
- Context windowing. Last 8 turns only; older screenshots are dropped entirely rather than resent.
- Conditional capture. Questions that don't need the screen don't pay for one. The heuristic is biased toward capturing: a needless screenshot costs milliseconds, a missing one makes the answer useless.
- Connection prewarm. The TLS handshake happens before you finish talking.
- A short system prompt, editable with ⌘P, plus ⌘E to expand on demand. Brevity by default beats a token cap, which truncates rather than condenses.
Search grounding (tools: [google_search]) is always on for Gemini and costs nothing
when unused — 664 ms without it, 686 ms with it, inside the noise. The model decides when
to search; grounded answers list their sources.
Speculative decoding. It runs inside the inference server, where a draft model's tokens are verified by the large model in one forward pass. No HTTP API exposes it.
The Draft→Refine toggle is the client-side cousin: a fast model answers immediately in
dim orange, then the strong model's reply replaces it in place. It doubles request volume
and hits rate limits about twice as fast, so it is off by default.
Report medians of at least 3 trials. A single sample here showed the fast configuration as
2× slower — a cold start. And test aliases against pinned versions: flash-lite-latest
beat the pinned gemini-3.1-flash-lite by 1.6 seconds. Newer is not faster, and "lite" is
not faster; only measurement tells you.