← Back to work

ToCoach

Personal Project

Replaces $1,500–4,000/month of human sales coaching with on-demand voice role-plays against AI buyer personas — 24/7, zero marginal cost, with an accountability engine that locks features if you skip practice.

31
LLM pipelines
103
IPC endpoints
34
SQLite tables
$0
Marginal cost
01

The problem it solves

Sales skill only improves one way: realistic practice with expert feedback. But human role-play coaching costs $75–200 an hour, has to be scheduled days out, and the written debrief lands 30+ minutes after the moment that mattered. The solo founders who most need reps get the least access to them.

And there's the part nobody solves: accountability. When practice is uncomfortable, people avoid it — they browse the dashboard, reread lessons, and quietly stop doing sessions. No coaching product notices. This one does, and it responds.

02

What I built

A local-first desktop app where you talk — out loud — to an AI prospect that pushes back like a real buyer: it interrupts, drops competitor names, and escalates when your answers are weak. Speech recognition and synthesis run on-device; the only external call is the LLM, and even that routes through a subscription CLI so marginal cost is zero. After every session, a fleet of LLM pipelines runs the entire coaching back-office — scoring, debriefs, curriculum, buyer research — while a coach brain maintains a deep model of the student and personalizes everything that follows.

Mic → PCM
capture
Whisper STT
(on-device)
Claude prospect
(CLI gateway)
Kokoro-82M TTS
(on-device)
Debrief +
pattern learning
Coach brain →
next session
03

Key features

04

System internals

ComponentWhat it does
process splitElectron main process orchestrates 7 backend modules (accountability, training gates, life-ops, onboarding brain, mission calendar, coach persona, telemetry); the renderer is a Vite + React 18 app with 40+ screens. 103 ipcMain.handle endpoints exposed through a single contextBridge API of ~107 methods — the renderer never touches Node directly.
LLM gatewayZero direct SDK calls anywhere. Every one of the 31 pipelines flows through one callClaude() helper that spawns the Claude CLI and pipes the prompt via stdin — chosen specifically so Windows shell operators in user text can never become injection.
voice — STTTwo independent paths: in-renderer Whisper tiny.en (ONNX, q8) fed by raw PCM captured at 4096-sample blocks and linearly resampled to 16 kHz; plus a main-process whisper.cpp path running base.en for higher accuracy. Guards for sub-0.3s clips and muted graphs; the recognizer returns errors as values, never throws.
voice — TTSKokoro-82M (ONNX, q8) decoding through Web Audio with a duration+5s safety timer, falling back to the OS Web Speech API when the model isn't ready — the prospect always speaks.
data layer34 SQLite tables (better-sqlite3, local-first): sessions, messages, daily metrics, vocabulary, coach intelligence/research/insights, presence, privileges, rewards, milestones, training gates, exam attempts, mission calendar, and a whitelisted-column deep student profile.
accountabilityAbsence-driven levels: 1 day = warning · 2–3 = lockdown with mandatory session · 4–6 = level drop, re-earned over 3 consecutive days · 7+ = recommit protocol. Feature privileges lock on their own schedules (quick meetings and mail mode after 2 days, stranger mode after 3, advanced difficulty after 4) and restore via streaks.
behavior detectionPer-screen dwell tracking catches "The Browser" (2 days of ≥10 min reading with zero sessions → info-avoidance lock) and "The Quitter" (3+ abandoned sessions in a week → the next 5 sessions require 8 full exchanges).
packagingelectron-builder → NSIS (Windows), DMG (macOS), AppImage (Linux); voice models auto-download on first run and ship as extra resources thereafter.
05

Tech stack

FrontendReact 18 · Vite 5 · Tailwind CSS · jsPDF · 40+ screens
DesktopElectron · contextBridge isolation · electron-builder (NSIS / DMG / AppImage)
AI / MLClaude (CLI subprocess) · Whisper tiny.en + base.en (Transformers.js / ONNX + whisper.cpp) · Kokoro-82M TTS (ONNX) · Web Speech fallback
Databasebetter-sqlite3 — 34-table local-first schema, whitelisted-column writes
IntegrationsDiscord webhook telemetry (server-side secrets) · file-based agent messaging · native OS notifications
06

Impact

31
Distinct LLM pipelines
Prospect simulation, debriefs, exams, curriculum, buyer research, self-assessment — all through one gateway
500+
Session configurations
16 scenarios × 12 personas × 3 difficulty tiers
$1.5–4k
Monthly coaching replaced
Human role-play coaching at market rates
100%
Back-office automated
At $0 marginal API cost via CLI subscription routing
07

Reliability & safety engineering

08

Decisions worth talking about

Why on-device STT and TTS

Whisper and Kokoro run fully local. Audio latency drops to near-zero, privacy is absolute — your fumbled pitches never leave the machine — and the product works on a plane. Two STT paths exist deliberately: a fast in-renderer tiny.en for live turns, and a main-process base.en when accuracy matters more than milliseconds.

Prompts over stdin, not argv

Every LLM call spawns the CLI and writes the prompt to stdin. The boring reason: on Windows, argv strings pass through cmd.exe parsing, and a user typing shell metacharacters mid-role-play would become a command injection. The gateway design closed that class of bug permanently — and gave every pipeline identical timeout, auth-failure, and recovery behavior for free.

The accountability engine is deterministic on purpose

Punishment levels, privilege locks, and behavior-pattern rules are plain code with exact thresholds — AI only garnishes the messaging. A discipline system that silently stops enforcing when an API is down teaches users that consequences are negotiable. This one physically can't.

Single-threaded WASM was the right trade

Multithreaded ONNX inference wants SharedArrayBuffer, which wants cross-origin-isolation headers — a day of debugging taught me that lesson. The renderer path pins inference to one thread: slightly slower transcription, zero deployment fragility across three operating systems.