Commit Graph

22 Commits

Author SHA1 Message Date
bc6c4842b5 Optimize startup and persist engine keys 2026-06-30 14:52:17 +02:00
586dc3dc3f release: v1.12.52 2026-06-30 13:53:08 +02:00
52994df70b feat: unified Library + character tags + shared cast (v1.10.0)
Restructure the sidebar into Voices / Speak / Setup groups and fuse the
Read Aloud and Script Rehearser features into one workspace:

- New combined Library section (Books · Theater Plays · Characters/Cast)
  with cross-links (Rehearse a book, Read Aloud a play).
- Character tags like voice tags: one record, many productions, reusable
  across books/scripts; seeded with origin book, editable in the editor.
- Shared cast resolution: opening a production fills empty cast slots from
  the character roster (matched by book OR tag); voice choices written back
  on save. Productions joined by normalized title (prodKey).
- Tags nav group for voices (distinct tags + counts, Cloned/Designed/Fav).
- Fold standalone Characters into Library; Read Aloud now a single entry.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 12:12:22 +02:00
495550bf6a Release v1.9.0 — Character Library + richer character sheets
Add a persistent, book-scoped Character Library (new Characters section,
IndexedDB) that auto-fills from Character-sheet analysis with editable cards.
Enrich extraction with six narrative fields (backstory, relationships,
motivation, fears, mannerisms, voice/speech) plus the greyscale Good↔Evil
alignment bar, arc arrow, and 5-area Deep Analysis. Add ⋯ separators between
non-contiguous passages in Recast unknown, and harden dialogue attribution
against hallucination with same-language emotion tags.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 21:22:40 +02:00
fff6e7e096 feat: add Seed Finder panel to voice inspector
Adds a collapsible "🎲 Seed Finder" panel to the voice inspector pane.
Select a voice, expand the panel, set a seed range (default 1–15), and
click Run to generate audio samples with different seeds.

Each result row has Play and "Use this seed" buttons. "Use this seed"
saves the chosen seed to the faster-qwen3-tts voices.json via the new
/api/tts-voice-seed proxy endpoint (which calls /voice-seed on the TTS
server). The saved row gets a ✓ marker.

Test sentence auto-selects DE/EN mixed or EN-only based on voice name.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 14:53:51 +02:00
345bec8a05 Fix chunked TTS failing on newline-delimited text (e.g. German bullet lists)
splitTextIntoChunks only split on sentence terminators (.!?), so structured
text separated by newlines was never chunked — the full page went as one
request, causing a TCP timeout that the browser reported as "Failed to fetch".

Fix: process each line individually before applying the sentence regex so
newline-separated segments become their own split points. Also move
generation.js from deferred batch E into the main feature batch C so
generateChunkedTts is always defined before the user can click Generate.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 03:41:31 +02:00
16c173d227 Improve app accessibility affordances 2026-06-05 22:08:13 +02:00
7b855394a5 Add searchable benchmark voice pickers 2026-06-05 15:44:13 +02:00
f469d428e2 Persist section reloads and reuse voice samples 2026-06-05 15:07:09 +02:00
40e42590cc Release v1.6.0: a11y (WCAG AA), i18n (DE), PWA, perf, tests, Cast UX
Cast: card/list views, sort & filter, online voice picker, "Hear a line"
sample button, AI character notes, import auto-save.

Platform: WCAG 2.1 AA accessibility pass; German UI translation + language
picker; installable PWA with offline shell; GZip + content-visibility
virtualization + lazy images + Rehearser PCM memory cap (mobile stability);
Playwright suite (desktop + iPhone); opt-in minified bundle build.

Fixes: screenplay parser false characters; Fish-Speech inline-tag tones;
narrator/voice pickers list full library; clone GUI rework; fish.audio
import dedup; voice-ID rename; bulk-delete modal.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 14:23:35 +02:00
d99395480a Add Script Rehearser; clean Connect Apps; About changelog; rework Try It Out
## Script Rehearser (new feature)
- New section s-rehearser.html + rehearser.js + nav/loader wiring
- Phase 1: paste/upload script (.txt), auto-detect characters from
  'CHARACTER: dialog' or ALL-CAPS screenplay format
- Phase 2: assign a TTS voice per character, or mark 'I play this'
- Phase 3: step-through rehearsal — synthesizes other characters via TTS,
  shows level-meter + oscilloscope for your own lines, records them from mic
- Phase 4: session summary with per-line audio playback + download

## Connect Apps
- Removed duplicate standalone MCP/speak/hotkey full-width cards
- Kept the integration-grid cards (they use the real server URL from JS)
- Added Global Hotkey Daemon as a proper integration card with snippet-hotkey
  populated by integrations.js (uses proxyBase URL dynamically)

## About page
- GET /api/changelog endpoint reads CHANGELOG.md and returns it as text
- Collapsible 'Changelog' <details> card fetches and displays it lazily

## Try It Out
- Reorganised into three cards: Voice & backend / Text to synthesize / Generate
- Backend help panel moved below the voice row (not in the same flex row)
- Style instruction field gains a dynamic badge ('style-aware ✓' / 'weak style')
  and a yellow warning when a non-style-aware backend is selected while the
  field is filled — wired to both backend-select change and input events

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 20:09:59 +02:00
0b3109cbf4 UX: faster load, skeleton fix, About cleanup, name hint, Connect Apps docs
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>
2026-05-31 19:19:20 +02:00
b3c1e4cc7f Fix JS caching root cause + robustness for sample text and STT dropdown
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>
2026-05-31 18:23:22 +02:00
c122089ef8 Parallel-load inactive sections alongside JS to cut startup time
Previously all 11 section HTMLs had to complete before JS loading began.
Now only the active section loads first (needed before JS runs so event
listeners find their DOM elements). The other 10 sections fetch in parallel
with utils + settings; an explicit await before the 9-module feature batch
guarantees all section HTML is injected before any feature module sets up
its DOM listeners. On a local server the HTML files finish well before
settings.js completes, so the await is typically instant.

Sequential steps cut from: sections(11∥) + utils + settings + features + ...
                        to: section(1) + max(utils+settings, sections(10∥)) + features + ...

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 20:21:35 +02:00
b33829ded5 Add skeleton loading, self-host assets, fix LLM empty response
Perceived startup speed:
- index.html: animated shimmer skeleton (header + toolbar + 8 voice cards)
  visible immediately; fades out when loader.js finishes
- WaveSurfer (57KB) and MDI icon font (394KB woff2) now served from
  static/vendor/ — removes 3 render-blocking external requests from <head>
- Flag-icons CSS loaded async (rel=preload onload trick) — non-blocking

loader.js:
- Fade out skeleton + remove from DOM (300ms transition)
- Reveal page-sections after JS finishes loading

Conversation playground:
- Qwen3 thinking mode fix: fall back to delta.reasoning_content when
  delta.content is empty so think-only LLM turns produce visible output
- Better error message with /no-think hint when LLM returns empty

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 17:28:42 +02:00
a5efac5da5 Speed up startup: parallel JS loading + versioned asset caching
loader.js:
- Fetch /api/version first; append ?v=<version> to every script URL
- Load scripts with async=false (fetch in parallel, execute in DOM order)
- 4 sequential batches instead of 17 sequential awaits:
    utils → settings → [9 feature modules] → init → [4 post-init] → nav
- 17 round-trips → 6 round-trips; 9 and 4 files now download in parallel
- Section HTML keeps ?v=<timestamp> (no-store, always fresh)

server.py:
- Add static_cache_headers middleware:
    /static/js/*?v=...  → Cache-Control: max-age=31536000, immutable
    /static/sections/*  → Cache-Control: no-store
    /static/* (no v=)   → Cache-Control: max-age=3600

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 17:11:55 +02:00
74e5181b7e Fix conversation input bar hidden when mic is blocked
- Move mic-blocked warning into conv-chat-window (prepend) so it scrolls
  with the chat instead of pushing the input bar off-screen
- Remove min-height:400px from conv-chat-window; give conv-chat-panel a
  viewport-relative height so the input bar is always visible at the bottom
- loader.js: append ?v=<timestamp> to section fetches to bust browser cache
  (was serving stale s-conversation.html after updates)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 14:20:52 +02:00
c7a1e35539 Security audit, modular refactor, and container-name field
Security fixes:
- Block /proc /sys /dev /run /boot in /api/browse-dirs (path traversal)
- Verify yt-dlp output stays inside TEMP_DIR before registration
- Remove Access-Control-Allow-Origin: * from /api/proxy-audio
- TTL-based temp file registry (default 2h) to prevent disk fill

Performance:
- Cache settings + routing rules in memory (mtime-checked); eliminates
  per-request disk reads on every TTS call

UI:
- Add container name (optional) field to Docker stack TTS/STT engine
  cards (Qwen3 Voice Clone, Voice Design, Custom Voice, Streaming,
  NVIDIA Magpie, Parakeet) — enables Stop/Start/Restart buttons on
  all engine cards, matching the existing Other Local TTS/STT cards

Refactor — backend:
- server.py: 5560 lines → 43-line entry point
- core/ package: constants, registry, validation, docker_client,
  config, routing, audio, voice, presets, tts_helpers
- routes/ package: admin, settings, library, stt, sources, docker,
  tts, conversation (FastAPI APIRouter modules)
- Dockerfile + docker-compose.yml updated to include core/ and routes/

Refactor — frontend:
- static/app.js: 8744 lines → 16 modules in static/js/
  utils, voice-inspector, voice-sources, integrations, routing,
  settings, voice-clone, voice-library, tts-preview, benchmark,
  stt, init, engines, ai-backends, generation, conversation
- static/loader.js updated to load modules sequentially

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 12:13:07 +02:00
6a78be7a28 Add Conversation Playground + XTTS v2 backend + VibeVoice voice fix
Conversation Playground (new section):
- WhatsApp-style chat UI with user/assistant speech bubbles
- Click-to-record mic button using MediaRecorder API
- STT → LLM streaming → TTS pipeline via SSE (POST /api/conversation/turn)
- LLM tokens stream into assistant bubble in real time
- Audio auto-plays when TTS synthesises the reply
- Right-side stats panel: STT / LLM TTFT / LLM total / TTS / Total with bar chart
- Turn history list with per-turn total time and pass/fail indicator
- Configurable: STT backend, LLM URL + model, TTS backend + voice, system prompt
- Conversation history maintained across turns (last 20 messages sent to LLM)
- GET /api/conversation/llm-models proxies model list from any OpenAI-compatible LLM

XTTS v2 backend:
- Registers xtts as a first-class TTS backend (xtts_url setting, display name,
  capabilities, health/voice discovery, OpenAI-compatible generation)
- Added XTTS URL field to Settings → Connections
- Use-as-TTS button now saves to xtts_url (not tts_url)
- Batch benchmark backend select now refreshes alongside perf/preview selectors

VibeVoice fix:
- Added /voices to _TTS_VOICE_ENDPOINTS so VibeVoice voices are discovered

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 23:27:57 +02:00
dc47aa0431 Add Benchmark page, MCP snippets, Captures settings, and history tracking
- New s-performance section: dedicated Benchmark nav entry with run form,
  per-session results table, RTF trend badge (faster/slower/stable), SVG
  sparkline chart, and a History card backed by localStorage (last 50 sessions)
- Performance tab removed from Try It Out; element IDs unchanged so JS works
- renderIntegrationSnippets: adds Python MCP server + Claude Code .mcp.json
  config snippets to the Connect Apps page (integration-card-wide styling)
- Save handler: persists all Captures settings fields (stt_language,
  stt_preferred_backend, auto_refine, refine_model, refine_* toggles,
  captures_default_voice) alongside existing settings
- CSS: integration-card-wide accent border, benchmark history rows, trend
  badges, sparkline wrapper, bench-history-toolbar

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 09:57:55 +02:00
28f5ec2e25 Redesign inspector pane, add searchable pickers, and style AI Backends tab
Inspector:
- Skinny 2-row header: 72px avatar + name/ID row / subtitle row / note row
- Searchable flag picker (dblclick flag icon) — filtered by voice language, falls back to ALL_FLAGS
- Searchable language picker (dblclick lang code) — shows full language names
- Tag reuse: entered tags persist to localStorage as datalist suggestions
- Compact active toggle (32×18px), slim save button (12px/4px padding)
- Show/hide eye toggle and "✓ Key saved" badge on API key fields

AI Backends (s-llms.html + style.css):
- Full CSS design: pill tabs with active accent, animated section transitions
- Service cards: icon bubbles, tier badges (Free/Demo/Paid), stat chips, endpoint rows, model tags
- Highlighted recommended card with accent border
- Dark code blocks for local service snippets with copy feedback
- Show/hide password toggle and auto-appearing "✓ Key saved" badge per card

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 11:23:27 +02:00
631ca16290 Studio Notebook redesign: warm cream theme, sidebar, multi-file static structure
- New light UI: fixed 220px sidebar, single scrolling page, 8 named sections
- Static files split by concern: style.css, app.js, loader.js, nav.js
- Each page section is its own partial in static/sections/s-*.html
- loader.js fetches all section partials in parallel, then loads app.js and nav.js
- All original functionality, element IDs, and API endpoints preserved

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 19:53:01 +02:00