Skip to content

feat: user-friendliness quick wins (CLI/first-run, Windows, MCP, GUI) + 3.9 CI fix#2

Merged
DavidTbilisi merged 3 commits into
masterfrom
feat/friendliness-quick-wins
Jun 3, 2026
Merged

feat: user-friendliness quick wins (CLI/first-run, Windows, MCP, GUI) + 3.9 CI fix#2
DavidTbilisi merged 3 commits into
masterfrom
feat/friendliness-quick-wins

Conversation

@DavidTbilisi

Copy link
Copy Markdown
Owner

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 report Saved <path>… open it manually instead of leaving the user in silence.
  • --stream with no media player prints an actionable warning rather than silently downgrading.
  • --check-deps (new --doctor alias) shows per-platform install commands for missing deps and an "All set" closer.
  • Running tts-ka with no input prints a friendly welcome (common commands + pointers to --doctor / --help-full); a one-time first-run nudge points to --doctor.

Windows

  • New extras/windows/Install-TTS_ka-Windows.ps1 orchestrator: verifies TTS_ka is on PATH and AutoHotkey v2 is present (with a winget hint), 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.
  • _LiveSession tracks synths_failed + last_error, surfaced in session_status / list_sessions. buffer_preview widened 80 → 400.

GUI

  • New first-shown Setup tab: inline dependency doctor (with Re-check), a voice picker with Preview, and a jump to the Speak tab.

CI

  • Fixed pre-existing TestSemaphore flakiness on Python 3.9 (asyncio.Semaphore() binds to the current loop at construction; ensured one exists in setup_method). Production is unaffected.

Tests

  • 683 pass locally (pytest -m "not slow"), coverage 78.94%.
  • Added: play_audio return values, DepRow.fix rendering, MCP blocking/no-player/echo/failure-field cases, and a display-guarded GUI smoke test asserting Setup is the first tab.
  • MCP and GUI tests skip cleanly where mcp/a display are absent (e.g. CI), so mcp is intentionally not added to the [test] extra (it requires Python ≥3.10; CI tests 3.9).

🤖 Generated with Claude Code

DavidTbilisi and others added 3 commits June 3, 2026 10:13
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>
@DavidTbilisi DavidTbilisi merged commit 62114dc into master Jun 3, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant