feat(voice): Kokoro local-TTS backend, take 2 — TypeScript, zero resident footprint (+ mute toggle & statusline indicator) - #1956
Open
HotSauceHacker wants to merge 2 commits into
Conversation
added 2 commits
August 22, 2026 14:32
…ve mute toggle, statusline indicator Fully-local private alternative to the ElevenLabs path, opt-in via LIFEOS_VOICE_BACKEND=kokoro. Reworked from PR danielmiessler#1465 to address the dependency-footprint concern: the daemon is now TypeScript/Bun via kokoro-js (no Python/pip), lazy-spawned by voice.ts on the first utterance, and exits itself after an idle timeout (no LaunchAgent, nothing resident). kokoro-js stays out of PULSE dependencies; opt-in installs it explicitly.
skhd and similar hotkey daemons run with a minimal PATH, so binding the bun-based VoiceMute.ts breaks for most installs. voice-mute-toggle.sh flips the same voice-mute.json state file in pure bash; the setup doc's skhd example now points at it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What and why
Follow-up to #1465, which was held out of v7.0.0 on dependency footprint (Python/ONNX runtime + a resident LaunchAgent). This resubmission keeps the same opt-in design and removes both concerns:
kokoro_daemon.ts) on kokoro-js. No pip, no manual model download — the ~90MB quantized ONNX model fetches itself to a local cache on first use.voice.tslazy-spawns the daemon on the first utterance; the daemon exits itself after 10 idle minutes (LIFEOS_KOKORO_IDLE_SECONDS). No LaunchAgent, no systemd unit, no manage step.kokoro-jsis deliberately not added to PULSE'spackage.json; opting in isbun add kokoro-jsplusLIFEOS_VOICE_BACKEND=kokoro. With the env var unset, the ElevenLabs path is byte-for-byte unchanged and nothing is installed or spawned.As before: fully local and private — no API key, no text or audio leaves the machine.
What's included
PULSE/VoiceServer/kokoro_daemon.ts— local daemon (GET /health,POST /speak), serialized playback, idle self-exit, env-configurable player for non-macOS (LIFEOS_KOKORO_PLAYER).PULSE/VoiceServer/voice.ts— backend selection (LIFEOS_VOICE_BACKEND=kokoro), lazy daemon spawn with health polling, live mute gate read fromvoice-mute.jsonon every notification (fail-open; desktop notifications unaffected).TOOLS/VoiceMute.ts—on|off|toggle|statusCLI, bindable to a hotkey.LIFEOS_StatusLine.sh— 🔊/🔇 glyph in the header, read live from the same state file.DOCUMENTATION/Notifications/KokoroVoiceBackend.md— setup (two steps), env vars, optional skhd hotkey guide.Tested
$KOKORO_CACHE(survivesbun install).voice.ts: cold start → health poll → utterance retry, end-to-end.LifeOSwordmark + ascent chip resolved in upstream's favor.