feat: user-friendliness quick wins (CLI/first-run, Windows, MCP, GUI) + 3.9 CI fix#2
Merged
Merged
Conversation
Eliminate silent failures and make setup self-diagnosing: - play_audio() returns bool; callers report when no player opened the file instead of leaving the user in silence. - --stream with no media player now prints an actionable warning. - --check-deps (new --doctor alias) shows per-platform install commands for missing deps and an "All set" closer on success. - No-args run prints a friendly welcome with common commands and points to --doctor / --help-full; one-time first-run nudge via marker file. - New extras/windows/Install-TTS_ka-Windows.ps1 orchestrator verifies prerequisites (TTS_ka on PATH, AutoHotkey v2) and runs both installers with a clear summary; readme gains a one-step setup section. Tests: 677 pass; added coverage for play_audio return values, DepRow.fix population, and report rendering. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
MCP server (mcp_server.py): - speak(blocking=True) now truly waits for the audio's measured duration (via ffprobe through pydub) before returning, so an agent can sequence speech without overlap. The return string echoes the resolved settings, and a failure to launch any player is reported instead of faked. - _LiveSession tracks synths_failed + last_error; both surface in session_status (and synths_failed in list_sessions) so an agent can detect a failed synthesis. buffer_preview widened 80 -> 400 chars. GUI (gui.py): - New "Setup" tab, shown first: step 1 runs the dependency doctor inline (with a Re-check button), step 2 is a voice picker with a Preview button, step 3 jumps to the Speak tab. Replaces the old JSON-editor- first experience for newcomers. Tests: added MCP cases (blocking wait, no-player error, settings echo, synth-failure fields) and a display-guarded GUI smoke test that verifies Setup is the first tab. 683 pass; readme MCP tool table updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
On Python 3.9 asyncio.Semaphore() binds to the current event loop at construction. pytest-asyncio can leave the main thread with no current (or a closed) loop after an async test, so the synchronous semaphore construction in TestSemaphore raised "There is no current event loop in thread 'MainThread'" — failing CI on the 3.9 matrix leg while 3.10/3.12 passed. Ensure a usable loop exists in setup_method. Production is unaffected: _generation_semaphore() is first called inside uvicorn's running loop. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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
User-friendliness quick wins across the CLI/first-run, Windows setup, MCP, and GUI surfaces, plus a CI fix for the Python 3.9 leg.
CLI + first-run
play_audio()returns whether a player launched; callers now reportSaved <path>… open it manuallyinstead of leaving the user in silence.--streamwith no media player prints an actionable warning rather than silently downgrading.--check-deps(new--doctoralias) shows per-platform install commands for missing deps and an "All set" closer.tts-kawith no input prints a friendly welcome (common commands + pointers to--doctor/--help-full); a one-time first-run nudge points to--doctor.Windows
extras/windows/Install-TTS_ka-Windows.ps1orchestrator: verifiesTTS_kais on PATH and AutoHotkey v2 is present (with awingethint), runs both existing installers, and prints a clear summary. README gains a one-step setup section.MCP server
speak(blocking=True)truly waits for the audio's measured duration before returning; reports when no player launched; echoes resolved settings._LiveSessiontrackssynths_failed+last_error, surfaced insession_status/list_sessions.buffer_previewwidened 80 → 400.GUI
CI
TestSemaphoreflakiness on Python 3.9 (asyncio.Semaphore()binds to the current loop at construction; ensured one exists insetup_method). Production is unaffected.Tests
pytest -m "not slow"), coverage 78.94%.play_audioreturn values,DepRow.fixrendering, MCP blocking/no-player/echo/failure-field cases, and a display-guarded GUI smoke test asserting Setup is the first tab.mcp/a display are absent (e.g. CI), somcpis intentionally not added to the[test]extra (it requires Python ≥3.10; CI tests 3.9).🤖 Generated with Claude Code