A minimal AI assistant that floats over your screen. It listens to the conversation, sees what's on your screen, and gives you a short suggestion in the moment: what to say or do.
The project's README from github.com/stormydayy/halo-overlay. As one markdown file: README.md.
A minimal AI assistant that floats over your screen. It listens to the conversation, sees what's on your screen, and gives you a short suggestion in the moment: what to say or do. Halo is a from-scratch rewrite of the idea behind sohzm/cheating-daddy, with no bundler, no vendored libraries, and support for any OpenAI-compatible model.
| Cheating Daddy | Halo | |
|---|---|---|
| Models | Gemini Live / Groq / OpenAI / local: four separate code paths | One OpenAI-compatible client: Gemini, Groq, OpenAI, OpenRouter, Ollama, LM Studio, or your own server |
| Speech | WebSocket stream to Gemini Live | VAD + Whisper-compatible API (Groq, OpenAI, or a local whisper.cpp / faster-whisper) |
| Screen | Screenshot on a timer | Continuous capture with a change detector and a rolling buffer of keyframes |
| Recording | None | Optional screen recording straight to disk as .webm |
| Security | nodeIntegration: true, no isolation |
contextIsolation, sandbox, strict CSP, every IPC call validated, API keys encrypted by the OS |
| Code | ~11,700 lines plus vendored libraries | ~3,100 lines, 0 runtime dependencies, no build step |
| Tests | None | 27 unit tests (npm test) |
Zoned out and lost the thread? Press Ctrl+Shift+Enter (or the button in the panel). Halo takes the transcript from the last 30 seconds to 5 minutes, plus a few screen keyframes, and answers in three lines:
Here's how it works:
getDisplayMedia ─▶ hidden <video> ─▶ every N ms: compare a 96×54 grayscale copy
│ │
│ (optional) ▼ did the screen change and then settle?
└▶ MediaRecorder ─▶ .webm on disk keyframe ─▶ Rewind buffer (3 min by default)
Only meaningful frames make it into the buffer: no duplicates, and nothing from the middle of an animation. The model gets a clean storyboard instead of a hundred identical screenshots. You can also pin frames in the Rewind panel, and they'll be sent along with your next question.
You'll need Node.js 20 or newer and Python 3.11+.
git clone https://github.com/stormydayy/halo-overlay
cd halo-overlay
npm install
npm start
The default model names are just sensible starting points, and they go out of date fast. The Model field is free text, so use whatever name your provider's docs currently list.
llama3.2-vision)./v1/audio/transcriptions (whisper.cpp server, faster-whisper-server) with the "Local server" preset.Local addresses (localhost, 192.168.*, 10.*) don't need an API key.
These work globally. You can change them in Settings.
| Action | Windows / Linux | macOS |
|---|---|---|
| Answer now | Ctrl+Enter |
⌘+Enter |
| Rewind (what did I miss) | Ctrl+Shift+Enter |
⌘+Shift+Enter |
| Show / hide window | Ctrl+\ |
⌘+\ |
| Click-through | Ctrl+M |
⌘+M |
| Move window | Ctrl+arrows |
⌥+arrows |
| Wipe data | Ctrl+Shift+E |
⌘+Shift+E |
| OS | System audio | Microphone |
|---|---|---|
| Windows | Loopback via getDisplayMedia |
Yes |
| macOS | SystemAudioDump helper (from the original project) |
Yes |
| Linux | Loopback if your environment supports it; otherwise microphone only | Yes |
If system audio isn't available, Halo tells you and carries on with the microphone and screen.
On macOS, grant Screen Recording and Microphone access under System Settings → Privacy & Security.
safeStorage: DPAPI / Keychain / libsecret) and are never sent to the UI.Ctrl+Shift+E erase them.Halo is a conversation aid, a bit like a stage prompter. Rules vary: many interviews, exams, employers and platforms prohibit outside help or recording, and laws on recording conversations differ from country to country. Check the rules wherever you use it, and tell the other people involved if the law or basic ethics call for it.
src/
├── main/ main process (Node)
│ ├── index.js window, shortcuts, IPC
│ ├── ai.js OpenAI-compatible client: streaming chat + speech recognition
│ ├── prompts.js profiles and message building (answer / rewind / recap)
│ ├── schema.js settings schema, validation, presets (pure module)
│ ├── store.js settings on disk + key encryption
│ ├── sessions.js session history; markdown.js handles export
│ ├── recorder.js streaming .webm recording to disk
│ └── macAudio.js macOS system audio (SystemAudioDump → 16 kHz mono)
├── preload.js narrow contextBridge: the only link to the UI
└── renderer/ UI (ES modules, no build)
├── main.js session, Rewind, AI requests, navigation
├── lib/capture.js screen capture, change detector, frame buffer, recording
├── lib/audio.js audio sources → VAD → WAV → speech-to-text
├── lib/vad.js speech segmentation + WAV encoder
├── lib/session.js session state, question detector
├── lib/md.js safe markdown renderer
└── views/ settings, history
test/ 27 tests (node:test): validation, SSE streaming against a mock server, VAD, DSP, …
npm start # run the app
npm run dev # run with DevTools
npm test # unit tests (no Electron needed, ~1 s)
npm run check # syntax check on every file
npm run format # prettier
npm run dist # build installers with electron-builder (output in dist/)
There's no build step: the sources run as they are. electron-builder is only needed for installers.
SystemAudioDump in this repo is built for Apple Silicon (arm64). System audio won't work on Intel Macs until you build the helper yourself from the source.GPL-3.0. The idea and the macOS audio helper come from sohzm/cheating-daddy and Mohammed-Yasin-Mulla/Sound.
A minimal AI assistant that floats over your screen. It listens to the conversation, sees what's on your screen, and gives you a short suggestion in the moment: what to say or do.