DEV Community

Cover image for I built an open source meeting recorder that runs on your laptop and drops any note it can't cite
SalimFlowStack
SalimFlowStack

Posted on AI-assisted

I built an open source meeting recorder that runs on your laptop and drops any note it can't cite

After a meeting, I usually remember the decision. I rarely remember why we made it.

The "why" was often on screen: a table, a diagram, a line of code someone was pointing at. Most meeting tools keep the audio and throw that part away. Most of them also want an account, a subscription, and your recordings on their servers.

So I built SayBack: an open source desktop app that records the conversation and what was shared, then writes notes where every point links back to the exact moment it came from.

It runs on your machine. No account, no SayBack server, no subscription.

Repo: https://github.com/0x2e73/sayback-app (MIT)

What it does

  • Captures your microphone, a window or a screen, and system audio where the platform allows it. You pick each source explicitly.
  • Transcribes the audio with timestamps.
  • Summarizes into key points, decisions, action items and open questions, using screenshots from the recording as context.
  • Jumps back: click a point in the notes and the video opens at that moment.
  • Organizes meetings into folders, with search across the whole library.

Local by default

A fresh install is configured for two small open source models:

Step Local (default) Optional, with your own key
Transcription whisper.cpp, base or small OpenAI, Gemini
Notes Ollama with gemma3:4b OpenAI, Claude, Gemini, any OpenAI-compatible API

In local mode, nothing leaves the computer. SayBack even refuses Ollama models that are really cloud models behind a local alias, before any data is sent.

If you choose a remote provider, only what the analysis needs is sent, with your own key. Keys are encrypted with Electron's safeStorage and never reach the renderer.

The part I care about most: notes that can't lie about their sources

A 4B model will happily invent a decision nobody made. Asking it nicely to "cite sources" is not enough, so the citations are checked in code.

1. Give the model something it can actually cite. An hour of meeting produces more than a thousand transcript segments, and small models can't copy that many IDs without mistakes. SayBack groups segments into blocks of about 45 seconds, each with one ID.

2. Require at least one source ID per note item. The prompt asks the model to copy IDs character for character.

3. Don't trust the answer. Every cited ID is checked against the set of IDs that really exist. Unknown IDs are removed, and an item left with no source is dropped:

function grounded(items: NoteItem[], sources: Set<string>): NoteItem[] {
  return items
    .map((item) => ({ ...item, sourceIds: item.sourceIds.filter((id) => sources.has(id)) }))
    .filter((item) => item.sourceIds.length > 0);
}
Enter fullscreen mode Exit fullscreen mode

One invented citation removes one item, not the whole summary. If nothing survives, the analysis fails with an error instead of showing you unsupported notes.

It doesn't make the model smarter. It does mean every line you read points to a real passage, and you can click it to check.

Under the hood

Electron, React and TypeScript. The main process owns SQLite, media files and the AI providers. The UI talks to it through a preload bridge and IPC channels validated with Zod.

src/
  main/       window, IPC, capture permissions
  preload/    secure bridge between UI and main process
  renderer/   React UI
  backend/    meeting rules, SQLite, media, AI adapters
  shared/     shared contracts and validation
Enter fullscreen mode Exit fullscreen mode

Local tools (ffmpeg, whisper-cli) are spawned without a shell and only receive validated paths and arguments.

Try it

There is no published installer yet. You need Node.js 22 or newer:

git clone https://github.com/0x2e73/sayback-app.git
cd sayback-app
npm ci
npm run dev
Enter fullscreen mode Exit fullscreen mode

On first launch, the app checks what is installed and opens the right guide if whisper.cpp, ffmpeg or Ollama is missing.

What's not there yet

This is an early project, so here is the honest list:

  • The UI, the docs and the generated notes are in French for now. English is an obvious next step, and a good first contribution.
  • Tested mainly on macOS (Apple Silicon). Windows and Linux should work in theory, but capture and local mode are unverified there.
  • Models are not bundled. You install whisper.cpp and Ollama yourself, following the guides.
  • Recordings and the local database are not encrypted by SayBack. Only API keys are.
  • No signed build, no in-app model download, no real speaker identification yet.

Where I'd love help

  • Windows and Linux testers: try capture and local mode, tell me what breaks.
  • Real meetings: how good and how fast are small models on a one-hour call on your machine?
  • Internationalization, starting with English.
  • One-click model install from the app. Detecting what's missing already works.

Issues and PRs are welcome: https://github.com/0x2e73/sayback-app

If you've built something local-first with small models, I'd like to hear how you keep them honest. What worked for you?

Top comments (0)