Skip to content
1jsjsPublic

About

English speaking coach built from what you actually said today — Bee on Apple Watch, wrist drills, Bee facts, real-life wins

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

SayBetter

An English speaking coach built from what you actually said today — grammar from real conversations, pronunciation from practice.

Language apps make you practise inside the app. But the mistakes that matter happen in real conversations — on calls, at work, with friends — and nobody is there to catch them. SayBetter uses Bee on an Apple Watch to collect the English you really spoke, coaches every sentence that needs it (with an explanation in your own language), turns the best corrections into drills that buzz on your wrist tomorrow, saves your recurring mistakes to Bee's memory, and then notices when you get them right in a real conversation.

Built for the Bee track of Build, Ship, Shape: Amazon Developer Hackathon (October 2026). Demo video: https://youtu.be/ — (link added on submission)

Today Practice
Today: a notebook of your own sentences Practice: try, hint, then check
Patterns Wrist drills
Patterns: slipped vs. got it right in real life Tomorrow, on your wrist
Pronunciation check (my real attempt) Watch drill app on my Apple Watch SE 3
Pronunciation: amber = unclear, red = heard as another word SayBetter Drill on a real Apple Watch: drills from Bee todos, 93% pass, done in Bee and Bee fact updated
Drills in the Bee app (real) What Bee remembers (real)
Bee app with three Say it todos and alarms Bee fact updated with real-life progress

The loop

 Apple Watch + Bee app ──► Bee cloud transcription
                                  │
          ┌───────────────────────┴────────────────────────┐
          ▼ live: bee stream --json                         ▼ nightly: bee conversations transcript
   saybetter watch                                    saybetter review   (launchd, 22:00)
          │                                                 │
          └──────────► English-only filter (code-switch aware) ◄──┘
                                  │
                                  ▼
                 LLM coach  (Claude via Claude Code headless · Gemini · offline rules)
          fix · natural version · Korean explanation · pattern · severity
          "used_correctly": a known weak pattern said RIGHT in real life
                                  │
     ┌──────────────┬─────────────┼──────────────────┬───────────────────────┐
     ▼              ▼             ▼                  ▼                       ▼
 macOS notice   daily notebook   bee todos create    bee facts create/update  real-life wins
 (live)         + web UI         "Say it: …" with    "I often slip on …        (wins.jsonl)
                (Today/Practice/  alarms 09/13/19     Slipped 2×, got it
                 Patterns/Drills) → wrist             right 1×"

Every arrow that touches Bee is a real call at runtime: bee stream, bee conversations list/transcript, bee todos create/list/complete, bee facts create/update — plus an Agent Skill (skills/saybetter-coach) that lets Claude Code / Codex quiz you using the Bee MCP server.

Pronunciation

Bee keeps no raw audio, so pronunciation is checked where SayBetter does get audio: when you practise. In Practice you say the corrected sentence; the browser records it and POST /api/pronounce runs whisper.cpp locally with word-level probabilities, aligns the words with the sentence you meant (contractions expanded) and marks each word ok, amber (unclear) or red (heard as a different word), with Korean tips for the sounds Korean speakers find hard (th, r/l, v/b, f/p, final -s/-ed). Up to three tries — the Duolingo/Busuu principle ("was it understood as intended?"), but on your own sentences. Results feed "Sounds to work on" in Patterns.

Needs a whisper.cpp model, e.g. ggml-large-v3-turbo-q5_0.bin in ~/.cache/whisper-cpp/ (or SAYBETTER_WHISPER_MODEL=/path/to/model.bin) and brew install whisper-cpp ffmpeg.

Watch drill app (watch/)

SayBetter Drill (SwiftUI, watchOS 10+) closes the loop on the wrist, and Bee holds both halves of it — what to practise and whether you did:

  1. What to practise comes from Bee. GET /api/drills reads your Bee todos live (bee todos list) and keeps the "Say it: …" ones SayBetter scheduled. Delete or complete one in the Bee app and it disappears from the watch.
  2. When the Bee reminder fires (Bee rewrites it, e.g. "time to say it out loud: 'That's a good point'"; with the iPhone locked it buzzes on the Apple Watch — checked on an SE 3), open SayBetter Drill on the watch and say the sentence. Scoring has three modes (Settings → Transcription): Auto scores on the watch with WhisperKit (openai_whisper-tiny.en) and falls back to the Mac, On watch uses only WhisperKit, Mac server sends the audio to the Mac's whisper.cpp. On-watch scoring was tested in the watchOS simulator; tiny.en scored 67% on a sentence the Mac scored 96%, so the real-watch demo uses Mac server.
  3. Whether you did it goes back to Bee. On a pass, POST /api/drills/complete runs bee todos complete <id> and updates the mistake pattern's Bee fact — "…practised out loud on my Apple Watch 2× (latest pronunciation score 88)" (or creates one), so your personal AI knows you are working on it. The nightly review keeps that clause when it rewrites the fact.

If Bee is unreachable the drill list falls back to the local copy; if on-device transcription is not possible it falls back to the Mac's whisper.cpp. Status: runs on a real Apple Watch SE 3 (installed from Xcode; the Mac and the watch on the same 2.4 GHz Wi-Fi) and in the watchOS simulator; the Bee side (live todo list, todo completion, fact update) was checked against a real Bee account. On the watch, the tiny.en model is noticeably less accurate than the Mac's large-v3-turbo, so the demo uses the "Mac server" mode. Build with xcodegen + Xcode; see watch/README.md. Run the server with SAYBETTER_HOST=0.0.0.0 saybetter serve so the watch can reach it on the LAN.

What makes it different

Speak, ELSA, Ringle, Loora and Duolingo all score practice inside the app. The few tools that look at real speech (ELSA Speech Analyzer, Yoodli, Ringle's lesson analysis) analyse one recorded call. SayBetter is the loop none of them close: your whole day of real English → focused corrections → drills on your wrist → and proof that you fixed it in your next real conversation. The headline metric is not a practice score; it is real-life wins.

Design choices backed by what learners and research say works:

  • Correct only what matters (Loora limits spoken corrections to a few; overload kills motivation): at most 8 items a day, most important first, ASR artefacts ignored.
  • Two-step correction — minimal fix first, then what a native speaker would actually say.
  • Elicitation before the answer (corrective-feedback research): Practice shows the rule first, then a cloze hint, then the answer.
  • Your own sentences as spaced-repetition cards (Anki/말해보카 style Leitner boxes: 1, 3, 7, 14 days).
  • One thing a day (Loora's key takeaway, Ringle's focus areas): Today opens with a single pattern to work on, and tomorrow's drills focus on it.

Quick start

git clone https://github.com/1jsjs/saybetter && cd saybetter
npm test                      # 35 tests, zero dependencies
npm link                      # puts `saybetter` on your PATH

# Bee CLI: enable Developer Mode in the Bee iOS app (Settings → tap Version 5×), then
npm i -g @beeai/cli && bee login

saybetter watch               # live coaching while you talk (macOS notifications)
saybetter review              # today's review → notebook, wrist drills, Bee facts
saybetter serve --open        # the web UI on http://localhost:4173
saybetter schedule --at 22:00 # nightly review via launchd

No Bee device? Everything runs offline on a recorded Bee stream with the deterministic coach:

SAYBETTER_LLM=fake SAYBETTER_HOME=/tmp/sb node bin/saybetter.js watch --dry-run --input fixtures/stream-sample.jsonl --window 1
SAYBETTER_HOME=/tmp/sb node bin/saybetter.js serve --open   # shows sample data when empty
Command What it does
saybetter watch [--window 8] follows bee stream, coaches English within seconds, notifies, records wins
saybetter review [--today|--minutes N|--conversation ID] [--drills 3] coaches what's new, writes the notebook, schedules ≤3 drills/day, saves/updates Bee facts
saybetter check "<sentence>" coach one sentence
saybetter patterns your top mistake patterns
saybetter serve [--port 4173] [--open] local web UI
saybetter schedule [--at 22:00] [--remove] nightly review with launchd
Env Meaning Default
SAYBETTER_LLM claude (Claude Code CLI, headless) · gemini (GEMINI_API_KEY) · fake (offline rules) claude
SAYBETTER_HOME where the notebook, drills, facts and wins live ~/.saybetter

How it is built

  • Node.js ≥ 20, zero npm dependencies; every Bee call goes through the official CLI so it uses your bee login.
  • src/english.js keeps only English, including English stretches inside Korean code-switched speech.
  • src/coach.js holds the prompt and normalises the model's JSON; fakeCoach is a deterministic rule engine for tests and offline demos. We benchmarked LanguageTool and Harper on real learner sentences: rule engines caught 2/5 and 0/5 of the speaking mistakes an LLM caught 5/5 (tense with time words, articles, explain me), so the LLM is the coach and rules are the offline fallback.
  • src/server.js + ui/ — a dependency-free web UI (hash routes, dark mode, mobile tab bar, Web Speech API practice, speechSynthesis to listen) reading plain files in ~/.saybetter.
  • Data stays on your machine; transcripts go only to the LLM backend you choose.

Privacy

SayBetter reads only your own Bee account. Bee transcripts do not label speakers on the live stream, so use it when you are the one speaking English or everyone present has agreed to Bee listening. It never coaches other people.

Files written to ~/.saybetter

history.jsonl (every coached sentence) · reports/YYYY-MM-DD.{json,md} · drills.json · facts.json · wins.jsonl · practice.jsonl · state.json · events.jsonl (raw Bee events for debugging).

Developer notes from building on Bee: FRICTION_LOG.md.

License

MIT

About

English speaking coach built from what you actually said today — Bee on Apple Watch, wrist drills, Bee facts, real-life wins

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages