Commit Graph

122 Commits

Author SHA1 Message Date
9d80ec27e7 Merge Reader/Casting/Rehearser pipeline into one guided workflow (v1.12.84)
- Add a 6-stage pipeline stepper (Source -> Cast Audiobook -> Cast Characters
  -> Script Rehearser -> Generate MP3s -> Audiobook) with direct, non-destructive
  jumps between stages and a prominent guided-tour look
- Split PDF import into an explicit "load" then "Extract Text" step, with
  in-browser OCR (Tesseract.js, vendored) to recover chapter headlines baked
  into a PDF as images instead of real text
- Fix casting feed silently merging pages after leaving/returning: segments
  now carry their own page number instead of re-guessing it from text
- Fix excessive "Unknown" speaker attribution: restore the attribution LLM's
  output token budget, which had been cut roughly in half and was truncating
  dialogue-dense passages
- Fix Theater Play library cards failing to open (dead pre-migration
  IndexedDB API calls, missing section navigation)
- Fix bulk "Set tag" wiping a voice's existing tags instead of adding to them
- Start merging Casting's feed with Script Rehearser's Stage UI: collapsible
  character sidebar, shared "paper" page styling, inline text editing
- Fix a performance regression from that merge (per-row listeners on every
  redraw) by moving to event delegation
- Various layout/clutter fixes: hide reader chrome until a document is
  loaded, collapse secondary settings by default, fix overlapping toolbar
  icons, fix duplicate "opening" notifications

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-03 17:45:38 +02:00
34e4bb99e1 Keep audiobook casting moving on slow LLMs 2026-06-30 22:06:39 +02:00
32a3c838fe Fix audiobook stop casting state 2026-06-30 21:04:53 +02:00
14d3e12ec8 Fix engines local container refresh race 2026-06-30 20:21:18 +02:00
dd697590ef Back user state with SQLite voice index 2026-06-30 15:06:43 +02:00
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
ad155f6c5c perf: voice list sessionStorage cache — instant render on reload (v1.12.20)
After a successful /api/voices fetch, results are written to sessionStorage
(key ttsvc_vc). On the next page load loadVoiceLibrary() reads the cache and
renders voices immediately before the network request completes, eliminating
the blank-list / skeleton flash entirely.

The background fetch always runs and overwrites the cache with fresh data.
Error handling is graceful: if the network fails but cache was served, the
error is suppressed (stale data stays visible). The Refresh button clears the
cache first to force a full reload cycle.

Silent-refresh logic (from v1.12.19) prevents the second loadVoiceLibrary()
call (engines.js batch E) from blanking already-rendered voices.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-28 02:00:48 +02:00
ce0f4c43bc fix: restore My Voices after infinite recursion + settings crash (v1.12.18-19)
Root cause 1 (v1.12.18): `window.loadVoiceLibrary = () => loadVoiceLibrary()`
overwrites the global binding the arrow function references, causing immediate
RangeError: Maximum call stack size exceeded on every call. Changed to direct
assignment `window.loadVoiceLibrary = loadVoiceLibrary`.

Root cause 2 (v1.12.18): `loadSettings()` called `renderSettingsAbout()` which
lives in conversation.js (batch E), loaded after init.js. Guard added with
typeof check; nav.js already calls it safely when the About section opens.

Also (v1.12.18): s-library.html duplicated cl-book-filter / cl-search / cl-grid
from s-characters.html, breaking getElementById. Characters panel in Library
now redirects to s-characters instead of duplicating its DOM nodes.

Also (v1.12.19): engines.js triggers a second loadVoiceLibrary() after nav.js
already rendered voices, blanking the list briefly. Second call now silently
re-fetches without clearing the list when voices are already present.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-28 01:57:49 +02:00
7e265f3e30 fix: null-safe loadSettings() — prevent crash on missing elements (v1.12.17)
loadSettings() was crashing with "Cannot set properties of null" because
many settings input elements were moved out of their original sections
during the Library restructure. All bare .value assignments are now
routed through a local sv() helper that silently skips absent elements.
This was also blocking My Voices from rendering on page load.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-28 00:36:18 +02:00
373aee8423 feat: sync batch benchmark results into My Voices (v1.12.16)
After a batch benchmark completes, successful entries are saved to each
voice's meta.json via POST /api/voice/meta. window.loadVoiceLibrary() is
then called so My Voices Factor + WPM columns update instantly without
a manual reload.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-28 00:20:15 +02:00
ef5321cb18 feat: lang/gender in batch benchmark list+results; sortable results table (v1.12.15)
Voice selection list now shows flag + gender symbol on each row.
Batch results table adds Lang and Gender columns. All columns are
sortable by clicking the header (↑↓ indicator); defaults to Factor
descending. Sort logic handles strings (locale) and numbers uniformly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-28 00:15:23 +02:00
5db93d55d1 feat: voices table shows only Factor+WPM; Benchmark gets full detail (v1.12.14)
Voices table: removed Length, Duration, Time — only Factor and WPM remain
from benchmark data. Setup → Benchmark batch results now shows Duration,
Factor (sorted fastest-first, colour-coded), Time, and WPM. Factor replaces
Avg RTF with the same data flipped to a more intuitive direction (higher=better).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-27 23:32:13 +02:00
90a481f8d8 feat: split Speed into Factor + Time columns, add colour coding (v1.12.13)
The old combined `21.8s · 1.30x` Speed cell is replaced by two separate
sortable columns:
- Factor (x.xx): audio÷render multiplier, green/amber/red colour-coded
- Time (Xs): total render time

Column order: Length · Duration · Factor · Time · WPM · Seed · dBFS · ...

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-27 23:19:33 +02:00
0606db101a feat: reorder columns, add Duration column, benchmark sentence presets (v1.12.12)
Column order now: Img·Play·Name·Lang·Gender·Length·Duration·WPM·Speed·
Seed·dBFS·Type·Source·Rating·Tags·Note·Active.
Duration shows synthesised audio length (b.audio_sec), sortable.
Preset dropdown offers 4 benchmark sentences (DE/EN narrative + DE/EN
tongue-twister) and a reset option.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-27 22:54:54 +02:00
ca3ce3adcb fix: live-update Speed and WPM cells during benchmark run (v1.12.11)
Previously the bench/wpm cells only updated after loadVoiceLibrary() at
the end of the full batch. Now each row is patched in-place immediately
after its voice finishes, for both batch and single-voice benchmarks.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-27 22:47:19 +02:00
c5181b499a feat: add WPM column + info tooltips to voice table (v1.12.10)
WPM (words per minute) is derived from the benchmark audio duration and
sentence word count, revealing how fast a voice speaks — independent of
GPU speed. 130–180 wpm is comfortable for audiobooks. Column is sortable.
Info (ⓘ) icons on Speed and WPM headers explain both metrics on hover.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-27 22:41:01 +02:00
73d991c2f8 feat: benchmark sorts by RTF factor, shows 2 decimal places (v1.12.9)
Speed column now displays 1.32× instead of 1.3× for better precision.
Sorting by Speed ranks by the RTF multiplier (faster = higher ×) rather
than raw elapsed time, so the sentence length no longer skews the ranking.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-27 22:36:57 +02:00
0c0bbb5ffd feat: auto-derive script name as SOURCE for Rehearser-cloned voices (v1.12.8)
Voices cloned from a Script Rehearsal now show the script title in the
SOURCE column without requiring manual entry. `_displaySource()` parses
the note field (`Rehearser · <title> · <character> — …`) and returns the
title segment as the source. Explicit `origin` values still take priority.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-27 20:36:34 +02:00
0bc3acc2ee feat: editable Source field + fish-audio fallback + bulk set source (v1.12.7)
- Add Source input to voice inspector panel (saves to origin in meta.json)
- Auto-detect fish-audio voices via tag — SOURCE column now shows
  "fish-audio" for tagged voices even without an explicit origin field
- Bulk "Set source" action in the multi-select toolbar
- Source cell in table reflects the live-displayed value and updates
  immediately when changed via the inspector

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-27 20:28:35 +02:00
04dee87710 feat: auto-save audiobook to Rehearser IndexedDB + Edit in Rehearser (v1.12.6)
- Casting completion auto-saves to Rehearser IndexedDB (same format
  as script rehearsals). Manual speaker corrections in the cast view
  debounce-save after 1.5s.
- rehId tracked across session (stored in localStorage draft) so
  updates go to the same record instead of creating duplicates.
- Voice assignments made in Script Rehearser survive an auto-update:
  only script text and emotions are overwritten; voice/instruct/soul
  are merged from the existing record.
- "Edit in Rehearser" button in the completed cast footer opens the
  saved record directly in Script Rehearser, ready for voice casting.
- Expose rehDbGetById + rehLoadRecord globally from rehearser.js.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-27 20:21:21 +02:00
9c975a651c feat: autosave casting progress to localStorage (v1.12.5)
Saves accumulated segments after every chunk. On page refresh or crash,
reopening Cast as Audiobook for the same document restores the session
automatically — shows a banner with completion % and save age.

Manual speaker reassignments in the cast view are also autosaved so
review corrections survive a refresh. Draft clears when the script is
saved to Script Rehearsals or a fresh Recast All is triggered.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-27 20:13:36 +02:00
87cac1f5f5 feat: expandable ⋯ dividers in Recast Unknown (v1.12.4)
Click any gap divider to reveal the hidden segments between two Unknown
passages inline — shows speaker + text so context is clear before
making an assignment. Displays line count ("42 lines hidden — click
to expand") so users know what they are opening.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-27 19:49:04 +02:00
7a75d1ecf4 feat: casting badge, navigate-away/back, live character count (v1.12.3)
- Pulsing blue dot on the Read Aloud nav item while casting is active
- Navigating away and returning restores the cast panel automatically
- Reassigning a segment's speaker decrements the old count so the
  Characters Found panel stays in sync; speakers at 0 disappear

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-27 19:45:41 +02:00
4f795e820c feat: noise gate, PDF search, sidebar active highlight, stats collapse, tooltip + dialogue fixes
- Conversation: adjustable noise gate slider (RMS threshold + 300 ms
  minimum burst duration) prevents short noise spikes from triggering
  STT; level meter shows gate position as a blue marker
- Conversation stats panel now collapsible (chevron button) to free
  chat width; floating expand button restores it; state persists
- Read Aloud: text search input in PDF toolbar (Enter = next hit,
  Shift+Enter = previous, Esc = clear)
- Sidebar: tooltip now works for all item types including sub-items
  that had no .nav-label span (text extracted by stripping icon/badge)
- Sidebar active section indicator added (.nav-tree-item.active was
  previously unstyled — active section now has bg + right accent bar)
- Casting audiobook: prompt instructs LLM to handle ?« / !« endings
  and unclosed » at passage end as dialogue; deterministic fallback
  also handles unclosed opening quote

Bumps to v1.12.2.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-27 16:48:48 +02:00
41f747a7b0 fix: icon-rail sidebar now shows per-item label tooltips instead of full flyout
Hovering the collapsed 56 px rail no longer expands the whole sidebar,
which was pushing the main content left and right. Each nav item now
shows a small floating tooltip (JS-positioned fixed div) next to its
icon on hover — layout stays completely stable.

Bumps to v1.12.1.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-27 16:00:56 +02:00
a4128788d6 feat: slim icon-rail sidebar, collapsible panels, Read Aloud fit-height (v1.12.0)
- Sidebar collapses to a 56px icon rail; hovering flies the full menu out as
  an overlay (icons + titles/nested items). Language picker moved to Settings.
- Unify settings collapsibles to the app's standard card-collapse style:
  Conversation, Read Aloud (drag-&-drop now inside), Try It Out, Casting panel.
- Read Aloud: reordered (settings → toolbar → document → transport/synth) and
  the document fits the viewport height so controls below stay visible; remove
  the redundant My Books card (lives in Library → Books).
- Conversation: stacked full-width config, fills viewport height; fix
  intermittent webm decode in hands-free mode (recorder restarts cleanly,
  in-browser WAV encode); barge-in via Live agent.
- Fix casting feed overflow that pushed the sidebar off-screen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 15:47:52 +02:00
fb7dcb52f8 feat: stacked Conversation config + browser WAV decode; changelog (v1.10.1)
- Conversation Playground: STT/LLM/TTS/System prompt now full-width stacked.
- Fix conversation mic upload on ARM64: decode recording in-browser to
  16 kHz mono WAV, bypassing server ffmpeg webm/EBML parser (with fallback).
- Document v1.10.0 (unified Library + character tags) and v1.10.1.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 14:35:57 +02:00
73c27944ac feat: collapsible nested sidebar groups
Group headers (Voice Actions, Speak, Setup) are now collapsible parents;
Tags nests under Library; Integrations + Settings nest under Setup.
Navigating a section auto-opens its whole ancestor tree chain.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 14:30:14 +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
464420b11c feat: richer default Seed Finder test sentence (v1.9.8)
Longer mixed DE/EN phrase covering dotted numbers, compound nouns,
umlauts, special characters, English technical vocabulary, time
formats and prose — reveals more of a voice's character per seed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 11:24:37 +02:00
217d92b91a fix: voice inspector TDZ crash + batch ops respect selection (v1.9.7)
- voice-inspector: move `curGender` const before its first use — it was
  declared at line 86 but referenced at line 61, causing a ReferenceError
  (temporal dead zone) that silently aborted selectVoice() on every click
- Calc dB, Precompute, Batch Seeds now filter to checked voices when a
  bulk selection is active, matching Benchmark's existing behaviour

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-27 10:06:06 +02:00
6b52a346d5 fix: stop casting feed from hijacking scroll and deleting visible rows
- Auto-scroll to bottom is now gated on the user being within 80px of
  the bottom. Scrolling up to review or edit a line freezes the feed
  in place — new rows are still added, but the viewport doesn't move.
- Row-trimming is likewise suppressed while the user is scrolled up,
  so old lines stay visible as long as they're being read/edited.
  Trim limit raised from 80 → 600 rows so almost nothing is evicted.
- A floating "↓ Live" pill button appears at the bottom of the feed
  whenever the user has scrolled up. Clicking it returns to the live
  bottom and re-enables auto-scroll.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:47:25 +02:00
a978e39e49 feat: expandable LLM panel + page markers in casting feed; fix page numbering
Casting view improvements:
- "LLM Reading…" row now shows a preview of the passage being processed.
  A chevron button expands it to a full scrollable view of the passage
  text (up to 260px), so you can follow what the LLM is reading live.
- Page-break dividers ("Page N") appear in the casting feed whenever the
  source PDF page changes, giving a real-time view of page boundaries.

Bug fix:
- Page numbers in the Rehearser script were 0-indexed (PDF-internal) so
  the first page break showed "Page 1" for what was PDF page 2, etc.
  Now always emits 1-indexed page numbers (\f${page+1}).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:23:19 +02:00
868ce6a7bd feat: show page numbers on page-break markers in Script Rehearser
When a PDF audiobook is cast and saved to the Rehearser, page breaks now
carry the source PDF page number. In the Stage view each divider renders
as "— Page N —" instead of the generic "— Page break —".

Implementation:
- audiobook.js: `audiobookBuildScript()` encodes the page number in the
  form-feed line (\fN instead of bare \f) at each page boundary.
- rehearser-parse.js: `parseScript()` now matches `line.startsWith('\f')`
  and extracts the trailing page number into `line.page`.
- rehearser.js: `buildScriptPage()` renders "— Page N —" when `line.page`
  is set; `toScript()` round-trips the number back (\fN) so it survives
  save/reload; `importPDFScript()` also encodes page numbers (\f<pageIdx+1>)
  when importing screenplay PDFs directly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:09:32 +02:00
01a2097c5e feat: add Native Speed control to Try it out and Read aloud
Exposes the `speed` parameter (0.5–2.0) on the TTS `/v1/audio/speech`
request so audio is generated at the target tempo natively via the
faster-qwen3-tts backend rather than post-processing.

- Backend: `/api/tts-preview` now extracts and forwards a `speed`
  override (clamped 0.1–4.0) through the same extra-params mechanism
  already used for seed/temperature; backends that reject it fall back
  cleanly via `_post_tts_with_fallback`.
- Try it out: "Native Speed" number input (0.5–2, step 0.05) added to
  the text card; value persists in localStorage per browser; passed as
  `extra` through `createTtsAudioSource` and `generateChunkedTts`.
- Read aloud: "Native Speed" control added to the generation controls
  row alongside seed/temperature; included in `readerGenParams()` and
  saved/restored with library documents (each book tracks its own speed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:01:08 +02:00
65e2784d2d Preserve audiobook pagination when saving to Rehearser (v1.9.2)
audiobookScopeText now records PDF page boundaries as character offsets in the
scope text; audiobookBuildScript realigns each segment against the source and
emits \f page-break markers at the nearest boundary. Saved/opened cast scripts
keep the book's pagination instead of collapsing to one flow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 21:49:51 +02:00
e62abbcd1d Fix character-sheet LLM URL + audiobook preview; Stage font controls (v1.9.1)
- Character sheets: stop sending the dead localhost:11434 default; fall back to
  the server's configured llm_url so extraction uses the same working LLM.
- Audiobook casting: hoist highlightText to module scope so the "Review & cast"
  manual-correction preview renders its segment rows again.
- Stage: unify narrator/dialog font size, add A-/A+ play text-size control
  (scales A4 + paginated views), and make the cast chip list collapsible.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 21:44:30 +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
18b4c1959c Release v1.8.1 2026-06-25 18:48:42 +02:00
ca599be5c3 style: reduce gap between stars in compact rating display 2026-06-23 10:40:48 +02:00
7e4c80d784 feat: simplify compact list meta row and update gender badges 2026-06-23 10:34:20 +02:00
7a296e4273 feat: use MDI silhouettes for avatars and add flag to compact meta row 2026-06-23 10:28:06 +02:00
307922b90c feat: Add row highlighting during batch voice benchmark 2026-06-23 09:13:41 +02:00
6ffba2d588 fix: Add new paths to config, fix Uvicorn logging, and update Storage settings 2026-06-22 21:36:59 +02:00
c26dabe296 feat: Implement dark theme variables and add save button to general settings 2026-06-22 21:35:16 +02:00
3908f365e5 fix: Abort fetch when cancelling audiobook casting and close UI immediately 2026-06-22 17:36:05 +02:00
3cc39b8ace fix: Restore edit mode button on page load and move select-all checkbox 2026-06-22 16:46:44 +02:00
af49bb4d6f fix: Correct CSS grid order for inline name input 2026-06-22 15:22:04 +02:00
cada45fb15 feat: Add Inline Table Edit Mode 2026-06-22 15:15:13 +02:00