DEV Community

Cover image for Blurt: say the errand out loud, find it in today's note.
Harshal Ranjhani
Harshal Ranjhani

Posted on AI-assisted

Blurt: say the errand out loud, find it in today's note.

Hacktoberfest Weekend Challenge: Build for a Friend Submission 🤝

This is a submission for the Hacktoberfest Weekend Challenge: Build for a Friend

What I Built

I built Blurt for a close friend who is busy enough that small promises fall out of their head. The thought shows up while they are cooking, walking, or halfway through something else: call Rohan about the venue tomorrow, buy milk, pick up rice. By the time a notes app is open, the thought is gone, or it is sitting in a voice memo they will not replay.

Blurt is a menu-bar app for their Mac. They hold Option-Space, say the thing, and let go. The microphone stops the moment the key comes up. On the machine, whisper.cpp writes down what they said, and a local Gemma model turns that sentence into a note they can actually use later. Today's file is ordinary Markdown in ~/Documents/Blurt.

Say "Remember to ask Rohan about the venue tomorrow" and the note looks like this:

# October 2, 2026

- 11:48 — **Personal** · Ask Rohan about the venue tomorrow.
  - [ ] Ask Rohan about the venue tomorrow.
  - Original: Remember to ask Rohan about the venue tomorrow.
Enter fullscreen mode Exit fullscreen mode

Each entry has a category (Shopping, Work, Personal, Ideas, or Other), a checkbox for every errand the model can point at in the original words, and the sentence Whisper heard. They check a box by changing [ ] to [x] in any editor. They can move the folder, grep it, or back it up with the tools they already have.

Blurt is a memory, and that is the whole job. It does not book the call, pick a calendar day for "tomorrow," or nag them. If the model is unsure, the original sentence is still there. A half-heard grocery mutter stays a note. It does not become a shopping list they never asked for.

Their notes also arrive in English, Hindi, and the mix of the two they actually speak. The default speech model is multilingual on purpose, and the organizer is told to keep the original language. "कल दूध खरीदना है।" should stay that sentence, filed under Shopping, with the date still said the way they said it.

Demo

What you should see: Ollama already running, then one double-click of Setup Blurt. After that, hold Option-Space, speak a short errand, release, and watch today's Markdown gain a category, a checkbox, and an Original: line. A second clip with the network off should still save a note.

Code

https://github.com/harshalranjhani/blurt

GitHub logo harshalranjhani / blurt

Local macOS hold-to-talk voice scratchpad with offline Whisper transcription and daily Markdown notes.

Blurt

Hold a shortcut, speak, and release. Blurt organizes the thought and saves tasks to today's Markdown note, entirely on your Mac. Built for a busy friend who has lots going on and finds it hard to remember things.

double-click Setup Blurt once
hold ⌥ Space → speak → release → Whisper → local Gemma → Markdown → notification

Say “Remember to ask Rohan about the venue tomorrow” and Blurt appends to ~/Documents/Blurt/2026-10-02.md:

# October 2, 2026

- 11:48 — **Personal** · Ask Rohan about the venue tomorrow.
  - [ ] Ask Rohan about the venue tomorrow.
  - Original: Remember to ask Rohan about the venue tomorrow.
Enter fullscreen mode Exit fullscreen mode

The v0.2 CLI labels voice and typed captures Shopping, Work, Personal, Ideas, or Other. It asks Gemma to extract explicit tasks and supplies a checkbox for each accepted task. Each task must include a verbatim source quote, validated before saving…

The current version is 0.3.1. For the friend, the path is short:

  1. Leave Ollama running.
  2. Download blurt-macos.zip from Releases and unzip it.
  3. Double-click Setup Blurt. The first run installs SoX, whisper.cpp, and jq, downloads the Whisper model, and builds the menu-bar app with the Command Line Tools that macOS already offers. There is no Xcode project.
  4. Allow Accessibility and the microphone when macOS asks.
  5. Hold Option-Space, speak, and release. The waveform in the menu bar is Blurt. Today's note is in ~/Documents/Blurt.

Ollama stays their one separate step. If it is not running yet, Blurt still saves the original words. They start Ollama, click the menu-bar icon, and choose Finish AI Setup, which pulls gemma3:1b (about 815 MB). Check Setup should then say Ready. The app opens again at login. They can quit it from the icon.

How I Built It

The open-source pieces are the product, not a feature bolted on the side.

Speech is whisper.cpp, the small GGML model, run only after the key is released. Organization is Gemma 3 1B (gemma3:1b) served by Ollama on http://127.0.0.1:11434. Each request uses a 2,048-token context, temperature zero, at most 384 output tokens, and keep_alive: 0, so the model unloads when the note is done. That size is there because the machine this is for is a MacBook with 8 GB of memory. Whisper exits before Gemma starts. Nothing in a capture talks to a cloud model.

Gemma is asked for JSON only: a cleaned sentence, one category, an unclear flag, and a task list. Every task must include an exact quote from the transcript. A small jq check keeps a task only when that quote is really in what was said. Version 0.3.1 is stricter about invention and looser about imperfect replies. If one quote is wrong, that task is dropped and the quoted ones stay. An unclear flag no longer throws away a reply that also contains a real errand. A task the model makes up, such as "buy a laptop" when nobody said that, never reaches the file. If the model times out, returns junk, or is not running, the original sentence is saved once, with a notification that says the AI result was unavailable.

I measured gemma3:1b (Q4_K_M) on Linux with CPU inference, which is not a Mac benchmark. Seven ordinary synthetic notes took about 17–20 seconds each. Five came back with the right category and the right tasks, including a Hindi shopping line. Two failed in ways I kept: a note with two errands ("call Rohan about the venue tomorrow and buy rice") kept the call and dropped the rice, and a Hinglish line was marked unclear. A note that tried to talk the model into inventing a laptop errand was rejected, and only the original text was saved. Peak model allocation reported by Ollama was about 837 MiB, which is the model, not the whole Mac. The 1B model will miss a second task and will stumble on mixed language. The original line is on the page so a wrong checkbox can be fixed by hand. A larger local Gemma tag can be selected with BLURT_AI_MODEL and checked with ./scripts/evaluate-ai.sh before anyone trusts it.

The capture pipeline is shell and jq. macos/BlurtApp.swift is a thin AppKit menu-bar wrapper, compiled on the Mac with swiftc during setup. There is no Electron app and no Python or Node runtime. Recording starts only for start or the shortcut. Temporary audio is removed after a successful capture. Notifications and the event log do not include the note.

GitHub Actions runs the shell syntax check and the smoke tests on macOS and Linux for every branch push and pull request. When both pass on a branch push, the workflow publishes blurt-macos.zip for that exact commit. Those tests mock the model. They do not prove that Gemma understood a sentence. The real-model script and a microphone pass on the Mac are separate, and the release notes say so.

Why Does Open Innovation Matter?

This only works if the thought never leaves the laptop. These are not polished prompts. They are half-sentences about a friend, a venue, a grocery run, sometimes in Hindi, sometimes mumbled. Sending that audio, and the transcript, to a closed transcription API and a closed chat model would mean an account, a per-note bill, and a copy of their day on someone else's server. It would also mean the app dies when the network does. After the two models are downloaded, Blurt captures with the network unplugged. I start Ollama with OLLAMA_NO_CLOUD=1 so its cloud features stay off.

Open weights are also why the behavior is checkable. The organizer prompt, the JSON schema, and the quote check are in the repo. I can read a bad note, see that Gemma invented a task or dropped one, and change the rule that accepts the reply. Swapping in another local Gemma tag is a config line, followed by the same evaluation script. A closed API would give me a finished paragraph and no way to demand a verbatim quote from the audio I already have on disk.

The notes stay files. There is no database and no sync service inside Blurt. If they want the folder in a private place, they point BLURT_NOTES_DIR there. If they want Blurt gone, the uninstaller removes the app and leaves the Markdown where it is.

Prize Categories

  • Best Use of Gemma. Gemma 3 1B, through Ollama, is the organizer. It categorizes the note, strips filler, and proposes tasks. Blurt keeps a task only when its evidence is a verbatim span of the transcript.
  • Best Use of GitHub Copilot. The project is automated with GitHub Actions: smoke tests on macOS and Linux gate a per-commit blurt-macos.zip, which is the build my friend installs.

Top comments (0)