Skip to content
MaybeSomeone-arc18Public

About

Get all your meetings notes the second they end, like excalidraw.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Voino

Listen. Understand. Edit. Voino turns what is said in meetings, lectures and discussions into editable notes and a hand-drawn, Excalidraw-style board you can rearrange and share.

Built with Flutter for Android and the web. Local-first: notes work with no account, no server and no API key. AI summaries are optional.

Status: prototype. Latest completed review baseline passed 60 Flutter tests and 12 Node tests; CI built a release web preview and Android debug Test Store APK. New mobile board/settings fixes are under review tests. Physical Android speech, storage and purchase acceptance are still pending. Main/site may lag the review branch. Production signing and live billing are not complete. See Known limitations.

Ask your notes (voice Q&A)

Talk to your notes by voice (Hindi, English or a mix) through Vaani voice agents.

  • Per-session consent names the third-party voice service and lists exactly what leaves the device: the note title, key points and action items as text, plus your voice while you talk. The raw transcript is never sent.
  • The Vaani API key lives only in server environment variables (VAANI_API_KEY, optional VAANI_AGENT_ID) on api/vaani-dispatch.js; it never reaches the client.
  • Each session injects the notes into a fenced NOTES_START/NOTES_END data block in the agent prompt; note text that tries to forge the fence is neutralized, and the agent answers only from the notes (it says it does not know otherwise).
  • Sessions run over WebRTC (LiveKit): the server route starts the session, the app connects with livekit_client.

How it works

Speak or type ──► editable transcript ──► notes ──► visual board ──► edit, save, share
                                            │
                     local extractor (default, offline)
                     Gemini with your own key (optional)
                     hosted summarizer on Vercel (optional)
  1. Listen. Tap the mic and talk. Words appear live as they are recognized. Or tap Type instead and paste a transcript.
  2. Notes. Review the transcript, fix mistakes, then make the board. Notes are labelled "Rule-based extract" or "AI summary" so you always know how they were made.
  3. Board. Notes become a mind-map you can edit like a whiteboard, then save as a file for someone else to open and edit.

Features

Capture

  • Android: the device's speech recognizer (speech_to_text).
  • Web: three modes: Cloud (the browser's own speech service, starts instantly, the default), On-device (multilingual whisper-tiny, Hindi + English auto-detected, about 40 MB downloaded once and cached, audio never leaves your machine) and Gemini (audio goes to Google through the Voino server, free tier with limits). On-device Whisper takes over automatically when the browser has no speech recognizer of its own. If the microphone is blocked, Voino says so in plain words instead of showing a raw error. A listening-language choice (browser default, Hindi or English India) is in Settings.
  • Type or paste always works. Typed text is never presented as recognized speech.
  • Clear all wipes the transcript, notes, board and any active recording in one tap.

Notes

  • Hosted AI notes by default on the web. A Vercel function (api/summarize.js) turns the transcript into a summary, key points, topics and action items with server-side keys, so visitors need no key. The first use asks for consent, and every note says how it was made. If the server is unavailable or rate limited, Voino falls back to local notes.
  • Local fallback, always. The rule-based extractor removes filler words, ranks sentences by keyword weight, groups related points into topics, links neighbouring points and pulls out action items. It keeps your original wording and never invents content. It selects sentences; it does not rewrite them.
  • Optional Gemini summaries with your own key. Open settings, paste one or more API keys (one per line), switch it on and press Test. Voino rotates through your keys and falls back to local notes if a request fails. Keys are kept in secure storage on your device and go only to Google.
  • Consent first. Voino asks before a transcript leaves your device, separately for Gemini and for the hosted summarizer.

Board

  • Auto layout: a central title card, one boxed group per topic around it, rose To do cards, mint point cards, labelled arrows for relationships, and circles on the key point and any decisions. Cards never overlap.
  • Excalidraw-style canvas: hand-drawn strokes and font, dashed sketchy shapes, dot grid, pan and zoom.
  • Edit everything: drag cards and shapes, resize shapes, double-tap to edit text or label an arrow, change card colors (◐), delete (×), add notes, connect cards, draw boxes and circles.
  • Undo (up to 60 steps), Delete selected, and keyboard shortcuts (Delete, Backspace, Ctrl+Z) on desktop.
  • Save and share: Save board .json downloads a file; Open board file (or Paste board JSON) loads one. Imported files are validated and clamped before use, so a shared board is safe to open.

Quick start

Requires the Flutter SDK (Dart ^3.12) and, for Android, a device or emulator.

flutter pub get
flutter run -d chrome     # web
flutter run               # connected Android device

Grant the microphone permission when asked. Speech may need internet, depending on the recognizer.

Tests

flutter analyze
flutter test                      # notes, board layout, Gemini client, board UI interactions
node --test tests/api.test.js     # hosted summarizer: key rotation, validation, rate limit

Build

flutter build apk --debug         # Android (com.maybesomeone.voino)
flutter build web --release       # web, output in build/web

Optional: Gemini and the hosted summarizer

With your own key (no server needed): open the settings icon in the app, paste your key(s), enable Use Gemini. Nothing else to deploy.

Hosted summarizer (for demos): deploy to Vercel and set these environment variables in the project settings:

Variable Purpose
GEMINI_KEYS Comma-separated Gemini API keys (GEMINI_API_KEYS also works). Rotated round-robin.
GEMINI_MODEL Optional. Defaults to gemini-2.5-flash.
ALLOWED_ORIGIN Optional CORS origin. Defaults to *.

Then users switch on Use Voino's hosted summarizer in settings. For Android, point the app at your deployment:

flutter build apk --dart-define=VOINO_API_URL=https://<your-app>.vercel.app/api/summarize

How the function protects itself: transcripts are capped at 12,000 characters, requests are limited to 6 per minute and 60 per day per IP, errors never echo keys or transcript text, and the model is instructed to use only what was said. The server then removes points, actions and summary sentences containing numbers the transcript never said, and drops owners nobody named. The rate limit is per serverless instance, so it is a guard against casual abuse, not a hard quota. Never put keys in the app or the repo.

Deploy to Vercel

vercel.json builds the Flutter web app (it clones stable Flutter, so the first build takes several minutes) and serves api/summarize.js as a function. Import the repo in Vercel, add the environment variables above, and deploy.

Project layout

lib/
  main.dart            UI: Listen / Notes / Board tabs, speech, settings
  logic.dart           speech stitching, Note model, local extractive notes
  gemini.dart          Gemini client, hosted-summarizer client, fallback order
  board.dart           card/link/shape models, notes -> board layout, safe JSON import
  board_controller.dart  board state, tools, selection, undo
  board_view.dart      Excalidraw-style canvas and toolbar
  rough.dart           hand-drawn stroke helpers
  live_transcript.dart live transcript panel while listening
  settings.dart        keys and consent flags (secure storage)
  whisper_web.dart     web-only bridge to web/whisper.js (whisper_stub.dart elsewhere)
web/whisper.js         in-browser Whisper via transformers.js
api/summarize.js       Vercel function (logic in api/_lib/core.js)
test/  tests/          Flutter tests and Node tests

More detail: ARCHITECTURE.md.

Privacy

  • Notes, the board and the transcript stay on your device unless you turn on an AI option. Nothing is saved between sessions except settings, so save the board file to keep your work.
  • The device or browser speech recognizer may send audio to its vendor. Whisper on web does not.
  • Turning on Gemini or the hosted summarizer sends the transcript to Google (through Voino's server for the hosted option, which does not store it). On Google's free tier Google may use the data to improve its products. Google's own terms apply.
  • Anonymous usage counters. Voino counts listening sessions started, boards created, and devices active per day as anonymous "+1" increments in the project's own database. No device id, transcript, notes or board content is ever sent for counting; there is nothing to read back about any person. Counting failures never affect the app.
  • Ask permission before recording other people.

Known limitations

  • Not yet verified on a real phone: live speech, the Android build, and the board's touch interactions.
  • The Vercel deployment has not been run yet, and Whisper's first load needs the internet (transformers.js from jsDelivr, the model from Hugging Face).
  • Whisper records in 5-second chunks, so a word can be clipped at a chunk boundary.
  • Local notes can miss points. They are extracts, not a summary, so check them against the transcript.
  • AI summaries can still be wrong. Review before relying on them.
  • No accounts, sync or offline app install. Android has no on-device speech model or LLM.

License

MIT. See LICENSE. The Caveat font is licensed under the SIL Open Font License.

Android RevenueCat Test Store demo

This debug Android build uses purchases_flutter and the voino_pro entitlement. Listening, typing, notes, board editing and text export stay free. Android board JSON save, copy, open and pasted import require an active entitlement returned by RevenueCat. Web remains free and does not configure native purchases. No history or cloud sync is implemented.

Build a debug APK with your project's public Test Store SDK key (not a secret API key):

flutter pub get
flutter test
flutter build apk --debug --dart-define=REVENUECAT_TEST_STORE_KEY=YOUR_PUBLIC_TEST_STORE_SDK_KEY

Configure the Test Store's current offering/package to grant voino_pro. Tap Test Pro, review the actual package metadata, then use the sandbox modal to simulate cancel/failure first and success last. Cancel/failure must leave board files locked. Success must return active voino_pro, enable save/open, and survive CustomerInfo refresh. Test Restore test purchases, then expiry/revocation. Test subscriptions expire quickly; the entitlement is checked again before file operations and on app resume. Connection failure locks only board files.

This is sandbox billing with no real charge or finalized production pricing. It is not a Google Play release: release builds deliberately refuse this Test Store setup. A production billing configuration and release/signing review are separate work. Test Store acceptance for Shipaton has not been confirmed by the organizer. Real-device purchase and save/open acceptance must be recorded before claiming those paths work.

Foreground listening sessions

Device speech keeps the user's listening intent across normal silence/session ends and attempts to restart after a short visible "Reconnecting microphone" gap. Android's native recognizer still has OS-imposed timeouts and can beep on restart; this is not gapless recording. Stop cancels queued restarts. Network, permission and other non-silence errors stop the session with a visible message. Backgrounding the app pauses capture and requires a tap to resume. Web Whisper uses its existing local chunk loop; it is not available in the Android APK.

Notes shows only nonempty sections. Expand Transcript to edit/listen; use the Board files overflow menu for JSON copy/save/open/paste with the same Pro checks.

Local recovery draft

Voino keeps one device-local recovery draft of your title, transcript, extracted notes and edited board. This is free, separate from Pro board-file export, and not history or cloud sync. Saves run after a short pause in edits and on app background. A saved/error status is shown in Notes. Clearing all also clears the recovery draft. Clearing app data, uninstalling, private browsing or storage errors can still lose it: copy/export important work. Do not claim phone recovery acceptance until close/reopen has been tested on the device.

Notes reading layout

Notes now uses the original paper/ink/gold palette with plain reading rows, section dividers, a collapsible transcript and fixed Copy notes/Make board actions. The decorative background stays on Listen and Board, not Notes.

Mobile board review and QA

Phones use Select, Move, + Note and More instead of ten wrapping controls. Move pans without editing cards; selected elements show Edit/Delete. Zoom buttons and Undo remain available. More contains circles, boxes, connections, fit and board files. Warm colors remain. This is Voino's own board, not Excalidraw file compatibility or collaboration.

Settings storage failure now reports that changes apply only to the current session instead of swallowing the failure. A failed write can be partial; re-save when storage is available. No account sync is claimed: Firebase project access/rules and two-user isolation must be verified before linking cloud data.

About

Get all your meetings notes the second they end, like excalidraw.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages