- Added a bounded playback boost with output limiting for generated voice audio, making quieter voices easier to hear without changing the app-owned playback safeguards.
- Added the
[voice] gain_dbTOML setting with validated0through12dB values and a6dB default. - Added
relay config set --playback-gain-db <0-12>for changing playback boost from the CLI, including decimal values. - Added a compact, auto-saving Playback volume boost slider to 设置 > Voice for whole-decibel adjustments.
- Preserved the emergency direct-
sayfallback without amplification. - Updated the app and CLI version to 2.3.0.
- Kept app-owned playback available while output-only audio is active and while temporary input capture is safely coordinated.
- Published bounded playback observations for local integrations without moving speech ownership out of the app.
- Added persistent voice reservations so new Relay lines receive stable, unused provider voices when available.
- Added
relay voice ensure --line <line> [--voice-id <voice-id>]for persona-agnostic automatic or explicit line-to-voice assignment. - Validated explicit voice IDs against the active provider catalog before persisting them.
- Fixed PATH-invoked
relaycommands so bundled Kokoro and Speechify helpers resolve from the real app bundle rather than the current working directory. - Updated the app and CLI version to 2.2.0.
- Fixed playback hanging indefinitely when a speech subprocess never exits, which left the menu bar showing playing with no audio until the app was restarted.
- Added a playback watchdog that force-recovers stalled playback, terminating the stalled process, resetting voice-command resolution, the audio player, and the synthesizer, and marking the stalled relay failed.
- The stall deadline scales with message length, and each playback phase gets its own deadline, so a long relay is never cut off mid-sentence and a slow voice synthesis never eats the budget for the audio that follows.
- Playback callbacks now verify that they still own the process, audio player, or utterance that produced them, so a late callback from recovered playback can no longer mark or interrupt the relay that replaced it.
- Stall recovery waits for the cancelled speech process to exit before starting the next relay, so recovery cannot briefly overlap two voices.
- Fixed the inactive-line combiner requeueing a relay that was skipped or cleared while the combiner was still running.
- Fixed
relay clearso it also removes relays stuck inspeakingand stops audio that is currently playing, instead of leaving the app speaking a relay that was already cleared. - Added
relay ff [--line <line>]to fast-forward past every queued relay by marking itskippedinstead of deleting it, so skipping the backlog no longer destroys relay history. - Updated the app and CLI version to 2.1.1.
- Added a Kokoro-compatible voice helper for direct-download builds that can use a user-installed local Kokoro venv without bundling Kokoro packages, model weights, voices, spaCy models, or caches.
- Added an invisible same-user Kokoro helper server that keeps
KPipelinewarm across relays and automatically shuts down when the active voice provider is no longerkokoro. - Kept the Kokoro helper server alive when a client disconnects before reading its response.
- Changed BYO voice output to a Core Audio-friendly
relay.audiopath so Kokoro can return WAV bytes without conversion. - Documented the optional Kokoro install path, missing-install failure mode, provider TOML example, local helper lifecycle, and Apache-2.0 Kokoro package/model license boundary.
- Updated the app and CLI version to 2.1.0.
- Made
relay configthe single CLI surface for TOML-backed advanced configuration. - Added
relay config set --voice-command,--combiner-command, and--cleanup-retention-minutes. - Removed the duplicate
relay settingscommand and maderelay combinerread-only; userelay config set --combiner-commandto change the combiner. - Preserved 1.1.2 upgrade migration from SQLite settings into
config.toml. - Added BYO voice command playback while keeping app-owned speech, mute, Focus, Ready, and Live safeguards.
- Added Speechify-compatible voice synthesis support for the direct-download app, including Keychain-based API-key lookup and rate-limit handling.
- Added provider voice configuration with sticky per-line voice IDs and optional stable assignment for new lines.
- Added local spoken-usage counters by provider, model, voice, and line so custom voice cost can be estimated without storing another copy of relay text.
- Added cleanup controls for old relay rows, spoken-usage buckets, and temporary voice audio files.
- Added 设置 UI capture and roundtrip verification for release-quality 设置 changes.
- Added Darwin notifications so the app wakes promptly when the CLI changes the relay queue or playback state.
- Optimized relay status refresh queries to reduce work while keeping 设置 and menu state current.
- Added Live mode to the overview docs.
- Updated the app and CLI version to 1.1.2.
- Fixed configured inactive-line combiners so the direct-download app executes the configured command instead of always using latest-only replacement.
- Kept combiner execution shell-free, bounded by timeout, and validated through JSON output before queuing the combined relay.
- Preserved latest-only fallback when no combiner is configured, when native combiner execution fails, or in the App Store-safe profile.
- Added regression coverage for CLI and native app enqueue paths, placeholder handling, and active-line changes while combining.
- Added Live mode for automatic playback of new relays.
- Plays queued relays in bounded batches by line so chatty lines do not starve other lines.
- Added Start Live and Stop Live menu controls.
- Added a green-dot menu bar status for Live mode.
- Updated the app and CLI version to 1.1.0.
- Shipped a signed direct-download macOS app.
- Bundled the
relayCLI with matching app and CLI versioning. - Added first-start setup for CLI installation, shortcut selection, voice selection, and Open at Login.
- Added Focus, Ready, and Mute queue controls with app-owned playback.