tts-voice-creator-clone-and.../CHANGELOG.md
mARTin-B78 a9d4c45a3c Improve engine card UX: unified controls, blue Connect, auto-apply, fix mic warning
Engine cards (all TTS + STT, dynamic Docker stack + static):
- Container name field now always visible on every card (was hidden for
  absent/not-installed containers)
- Connect button moved out of URL row into a dedicated dc-controls-row;
  restyled as solid blue primary CTA
- Connect now toggles to Disconnect (green) when reachable, persists state
- On successful connect, URL is auto-applied to Settings so the backend
  appears in TTS/STT dropdowns immediately — no separate "Use as" click needed
- "Use as TTS/STT" button updated: larger, teal "apply" style, tooltip,
  gains .active highlight once applied, right-aligned as the trailing action
- Unified control order on every card: [Connect/Disconnect] [Stop|Start|Restart] [Use as →]
- initStaticDockerManagement rebuilt to use the same dc-controls-row layout
  as dynamic cards, moving .llm-local-ping from URL row at init time

Conversation section:
- Fix chrome://flags URL being white-on-grey inside the mic-blocked warning
  box (global code{background:var(--panel)} overrode the inherited white text)
- Inline-styled the <code> element with a dark translucent background
- Added a Copy button so users can copy the URL without selecting invisible text

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 12:59:59 +02:00

8.9 KiB

Changelog

All notable changes to TTS Voice Creator — Clone and Design are documented here. Format follows Keep a Changelog.


[Unreleased] — 2026-05-29

Added

  • Container name field on all engine cards — every TTS and STT engine card (Docker stack cards and static "Other Local" cards) now always shows the Docker container name input row. Previously absent/not-installed cards hid it; now it is always visible so the container can be pre-configured before starting.

  • Connect / Disconnect toggle — the Connect button now shows "Disconnect" when already connected (with a green check-network icon) and toggles back on click, persisting state in localStorage.

  • Auto-apply on Connect — when a successful connection probe is completed the URL is automatically saved to Settings and the backend becomes available in the TTS / STT dropdown menus immediately, without requiring the user to also click "Use as TTS/STT". The manual "Use as" button still exists for overrides and shows an active highlight once applied.

Changed

  • Connect button — moved out of the URL input row into a dedicated dc-controls-row below the URL and container-name inputs. Restyled as a solid blue primary CTA button (was a small teal outline button).

  • "Use as TTS / STT" — made visually distinct as a teal "apply" action (larger padding, bolder border, chevron icon). Tooltip explains it sets the URL in Settings and enables the backend in dropdowns. Gains .active class once the URL has been applied.

  • Unified controls row layout — all engine cards now follow the same left-to-right order: [Connect/Disconnect] [Stop | Start | Restart] [Use as →]. Docker action buttons are hidden until a container name is entered; the Use-as button is right-aligned via margin-left: auto.

  • Static engine cards (initStaticDockerManagement) — rebuilt to use the same dc-controls-row structure as the dynamic Docker stack cards. The existing .llm-local-ping button is moved from inside the URL row into the controls row at initialisation time.

Fixed

  • chrome://flags/… URL unreadable in microphone-blocked warning — the global code { background: var(--panel) } rule caused the URL text to render as white-on-light-grey inside the red warning box. Fixed by applying inline styles (background: rgba(0,0,0,.35); color: #fff) directly on the <code> element and adding a "Copy" button so users can copy the URL without having to manually select invisible text.

[Unreleased] — 2026-05-29

Security

  • Fixed path traversal in /api/browse-dirs — Added a _BROWSE_BLOCKED blocklist (/proc, /sys, /dev, /run, /boot). Requests for paths under these directories now return HTTP 403 instead of listing kernel/system files.

  • Hardened yt-dlp output path — After a YouTube download completes the resolved output path is verified to be inside TEMP_DIR with .relative_to(). A file written outside the temp directory is rejected with an SSE error event and never registered.

  • Removed CORS wildcard on /api/proxy-audio — The Access-Control-Allow-Origin: * header was unnecessary (all callers are same-origin) and exposed proxied audio to arbitrary cross-origin requests. Header removed.

  • Temp file registry now enforces a TTL_registry is now a dict[str, tuple[Path, float]] storing each entry with a creation timestamp. _registry_gc() evicts entries older than TEMP_FILE_TTL_SECONDS (default 2 hours, configurable via env var) and unlinks their files, preventing unbounded disk growth.

Performance

  • Settings and routing rules cached in memory_load_settings() and _load_tts_routes() previously read from disk on every API request. Both now use mtime-checked in-memory caches (_settings_cache, _routes_cache) that are invalidated automatically on write. Eliminates dozens of redundant file reads per TTS synthesis call.

Added

  • Container name field on Docker stack TTS/STT cards — The engine cards rendered dynamically in the Engines → Text to Speech and Engines → Speech to Text sections (Qwen3 Voice Clone, Voice Design, Custom Voice, Streaming, NVIDIA Magpie, Parakeet ASR) now show the same container name (optional) input row that the Other Local TTS/STT cards already had. Typing a container name immediately enables Stop / Start / Restart buttons wired to the Docker API. The static STT cards (faster-whisper-server, whisper.cpp) received the same treatment via initStaticDockerManagement().

Refactored

Backend — server.py split into core/ + routes/ packages

server.py went from 5,560 lines to a 43-line entry point that creates the FastAPI app, registers routers, and mounts static files. All logic was extracted into single-responsibility modules:

core/ — pure utilities (no FastAPI decorators)

Module Responsibility
constants.py Boot-time env defaults, CONFIG_DIR/CONFIG_FILE/STATIC_DIR paths, in-memory log buffer
registry.py TEMP_DIR, TTL-based temp file registry (_registry_put/get/gc)
validation.py _validate_http_url, _normalize_service_url, _copy_limited, _safe_child_path
docker_client.py Raw Unix-socket Docker HTTP client (_docker_get_json, _docker_post)
config.py Settings load/save/normalize, TTS stability helpers, backend URL resolution
routing.py TTS route rules load/save/resolve, language detection, routing log
audio.py _to_wav_24k/16k, _trim, _duration, _normalize_segment, auto-trim scoring
voice.py Voice metadata helpers, backup management, benchmark helpers
presets.py Voice Design preset load/save, virtual voice resolution
tts_helpers.py TTS request helpers, streaming, NVIDIA/VibeVoice/XTTS backends, audio proxy

routes/ — FastAPI APIRouter modules

Module Routes
admin.py GET /, GET /favicon.ico, GET /api/browse-dirs, GET /robots.txt
settings.py /api/settings, /api/tts-routes, /api/tts-routing-log, /api/logs, /api/voice-design-presets
library.py All /api/voice* and /api/voices*, /api/save, /api/upload, /api/route-sounds*, /api/audio/{fid}, /api/auto-trim, /api/process
stt.py /api/stt-backends, /api/transcribe, /api/transcribe-bytes
sources.py /api/voice-sources, /api/import-source-audio, /api/proxy-audio, /api/quick-import-voice, /api/download-yt, /api/elevenlabs/voices
docker.py /api/local-containers/*, /api/probe-url
tts.py /api/tts-preview, /api/tts-style-variation, /api/tts-stream-*, /api/voice-design, /v1/*, /api/tts-voices, /api/tts-backends, restart endpoints
conversation.py /api/refine-text, /api/rewrite-with-persona, /api/audio/effects, /api/voices/export, /api/voices/import, /speak*, /mcp, /api/conversation/*

Dockerfile updated to COPY core/ core/ and COPY routes/ routes/. docker-compose.yml updated to mount ./core:/app/core:ro and ./routes:/app/routes:ro.

Frontend — static/app.js split into static/js/ modules

app.js (8,744 lines) split into 16 focused modules totalling the same 8,744 lines. static/loader.js updated to load them sequentially in dependency order.

Module Lines Responsibility
utils.js 364 $, toast, escHtml, debounce, theme, language/flag helpers, searchable picker, tab helpers
voice-inspector.js 397 3-pane voice workbench (selectVoice, updateInspector)
voice-sources.js 277 External voice source scraping UI (loadGetVoices, renderGetVoices)
integrations.js 211 Code snippet generation for SillyTavern, Open WebUI, HA, curl, MCP
routing.js 542 TTS routing rules editor
settings.js 385 loadSettings, applyAndSaveSettings, settings panel
voice-clone.js 774 WaveSurfer waveform, drop zone, microphone, trim UI, voice design dialog
voice-library.js 2654 Full voice library: list, row rendering, operations (save, rename, delete, normalize, benchmark)
tts-preview.js 528 fetchTtsPreviewBlob, createTtsAudioSource, preview panel
benchmark.js 218 Batch benchmark section
stt.js 287 STT→TTS playground, refreshSttBackends
init.js 49 App bootstrap (calls loadSettings, syncs UI state)
engines.js 625 ElevenLabs browser, custom engine cards, Docker container management
ai-backends.js 520 AI backend cards, LLM snippet collapse, initStaticDockerManagement, collapsible cards
generation.js 393 WAV merge, chunked TTS, generation history, playlist, audio effects, LLM refinement
conversation.js 520 Settings logs/about, voices import, conversation playground

Earlier history

See git log for the full commit history prior to this release.