Loader:
- Post-init modules (engines, ai-backends, generation, conversation) now
load AFTER the skeleton is removed instead of before. The UI is visible
~500 ms sooner on average; those four modules load while the user is
already browsing Voices / Clone / Design.
- Removed the sttReady event approach that was triggering a duplicate
/api/stt-backends call; init.js already populates all STT selects once
on startup.
Skeleton:
- Replaced the card-grid placeholder with a two-column workbench skeleton
(voice list rows on the left + inspector placeholder on the right) that
matches the real My Voices layout.
Connect Apps:
- MCP Server, /speak REST endpoint, and Global hotkey daemon sections
moved from Settings → About to Connect Apps, where they belong.
- About page now has GitHub + Releases links instead.
Clone section:
- Added a hint note beneath the sample-text textarea reminding the user
to replace the placeholder name (Sam / Alex / Marco …) with their own.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Root cause: VERSION was not volume-mounted, so the server always reported
1.2.0, causing browsers to serve 1-year-immutable cached JS even after
code changes.
Fixes:
- docker-compose.yml: add ./VERSION:/app/VERSION:ro volume mount.
After `docker compose up -d`, the server reads the current VERSION file
and JS is cache-busted by the correct version string.
- loader.js: append session timestamp to _appVersion so every page load
generates a unique JS URL. JS is always fresh regardless of whether
VERSION is current, at the cost of one network round-trip per file per
session (acceptable for a local tool).
- s-clone.html: embed EN default text directly in the textarea so the
field is never empty even before JS runs.
- voice-clone.js: remove the 'skip if already filled' guard in
initCloneSampleText so navigating back always resets to the language
text; call refreshSttBackends on load with sttReady event fallback.
- stt.js: dispatch 'sttReady' event after all STT listeners are wired.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1. Sample text: expose initCloneSampleText as a window function and call
it from nav.js runSideEffects when the clone section is activated,
ensuring the textarea is always populated even if the IIFE ran before
the element existed.
2. Better sample texts: all 8 languages rewritten to ~38 words / ~15 s,
first-person, phonetically rich, proper Unicode diacritics.
3. Live mic monitor: a level-meter (18-bar) + scrolling oscilloscope
canvas (ring-buffer, 300 px, colour-coded) added to the microphone
card. "Check level" / "Stop monitor" buttons start/stop it
independently; clicking Record starts it automatically.
Uses raw mic constraints (no echo-cancel / AGC) for cleaner voice clone
audio. Mic gain slider and dB readout included.
4. Recording quality: MediaRecorder now requests audioBitsPerSecond:256000
in both voice-clone.js and stt.js.
5. STT engine picker: Recognition engine <select> + Refresh button added
above the Auto-transcribe button in Step 3. refreshSttBackends() now
syncs both stt-tts-stt-backend and clone-stt-backend. The transcribe
call passes the chosen backend to /api/transcribe.
6. File input: explicit extension list added to accept= for OGG/OPUS.
7. CSS: .mic-live-wave style added (dark/light theme variants).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>