#1328 merged without a CHANGELOG entry. Per the changelog rule that is
the immediate next commit rather than backlog, since release.yml extracts
the section verbatim as the release body.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The 'more local open-source' section grows from a bare two-row table
into proper cards: verified logo assets from each repo, a one-line
pitch plus grounded detail (from the repos' own metadata), star badges,
and links. The Sponsor/Donate section gets a one-line cross-promo —
'more apps from the creator' — since a star on a sibling project is
support too.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Cut the repetition, keep the charm: the local-first pitch was made three
times before the first screenshot (quote + cell table + CTA block — now
just the quote), Discord had four CTAs (now two), and the Intel-Mac
caveat appeared three times (now once per context, linked). Screenshots
trimmed 8 -> 6. Engine name lists that repeated the validated matrices
inline (Why table, FAQ) now point at the matrices instead. Fixed the FAQ
claiming '10 TTS engines' (it's 14). Added a download button to the hero
so a new user's path from first glance to installed is one click.
Docs-drift + install-docs validators and the CJK guard all pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Add a what-you-need line (RAM/disk/GPU from the README requirements
table, compressed pull sizes measured from the registry) so homelab
users can size the deployment before pulling.
- Update stale version examples (:0.3.6 / :0.3.17 -> :0.3.22).
- Fix the 'main is always one patch ahead' claim — with
AUTO_VERSION_BUMP off, main can equal the released version; say
'at or ahead of the last release', which is true in both modes.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A release now has an explicit channel checklist (docs/RELEASING.md §5b):
GH Release + stable updater manifest, preview updater channel, GHCR +
Docker Hub in both CUDA and ROCm flavors, and the Docker Hub overview
sync (whose continue-on-error step must be verified by step log — it
403s silently on tokens without description-edit scope).
Preview/RC policy is now enforced, not just documented: release.yml's
preview-gate fails publish_preview dispatches from any branch but main,
since the preview manifest and rolling Docker tags all track main.
Also fixes docs/RELEASING.md §4-5, which still described the pre-2026-06
versioning scheme (tauri.conf.json + Cargo.toml as sources, 'Tauri
ignores package.json') — the exact opposite of the current single-source
rule — and docs/update-channels.md, which invited previews off feature
branches.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
#1159 and #1160 merged without changelog entries; also covers the
useAppData silent-catch logging absorbed from declined PR #1158 and the
#1160 follow-up traceback sweep.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The QueueFull-recovery block was misread as racing with consumers (an
AI-generated PR proposed "fixing" it). Pin down why it is correct so the
misreading does not recur. Comment-only change.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The five data-loading callbacks (profiles, generation history, dub
history, projects, export history) swallowed API failures with empty
catch blocks — a failed fetch looked identical to an empty library, and
"my voices vanished" reports carried nothing to diagnose. Each catch
now console.warn-s with an accurate per-fetch message (the declined PR
copy-pasted mismatched ones). The backend-startup retry loop and the
localStorage-restore catch are left silent on purpose: failing there is
the expected path they exist to absorb.
Co-authored-by: bultodepapas <bultodepapas@gmail.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
#1160 fixed one traceback-losing logger.error in dub_pipeline.save_job;
this sweeps the remaining class. 19 sites across 10 files where a real,
unexpected failure was summarized as "...: %s" at ERROR level — losing
the stack trace that makes crash reports diagnosable — now use
logger.exception (diarization/ASR crashes, dictation load/final
failures, ffmpeg mixes that silently degrade output, Smart Fit retime
fallbacks, RVC init/inference, models.yaml catalog load, gallery
search/download 500s, dub-history JSON decode, MCP CLI fatal exit).
Deliberately left alone: WARNING/INFO/DEBUG logs, expected classes with
self-sufficient messages (GPU/ASR timeouts, request validation,
cryptography-availability checks), sites that re-raise immediately
(db migration, _ensure_mcp), subprocess returncode checks where stderr
IS the diagnosis, and sites already logging exc_info/format_exc.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The #1159 fix merged without a test: the existing
BootstrapSplashFailedRecovery.test.jsx only exercises the
useBootstrapStage hook, so nothing ever rendered <BootstrapSplash
stage="failed"> and CI could not see the ReferenceError. These tests
mount the failed card directly (recoverable + unrecoverable variants);
both throw on the pre-fix line order and pass on the fixed one.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A Windows dub export died at ffmpeg *spawn* with [WinError 206] — the
mux argv scales with tracks/segments and exceeded CreateProcess's 32,767-
char limit — but the catch-all told the user their (8-char) filename was
too long AND to check whether ffmpeg was installed.
- explain_ffmpeg_failure() maps the three real failure modes to their own
advice: argv-too-long (names the limit + the actual size, suggests fewer
languages per export), ffmpeg-unlaunchable (the only case that suggests
checking the install / FFMPEG_PATH), and ffmpeg-ran-and-failed (surfaces
ffmpeg's stderr, no install advice). All three dub_export catch sites
(video mux, audio export, MP3 encode) now use it.
- run_ffmpeg() on Windows moves an oversized -filter_complex graph (the
dominant argv consumer — the bed-mix/apad branches grow per track) into
a -filter_complex_script temp file, so the spawn never hits the limit
in the first place; the script file is removed after the run.
Regression tests: tests/test_ffmpeg_failure_diagnosis.py.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two Windows-only backend crash classes, one boundary (process spawn/stdio):
forrtl: error (200) (#1153 and the crash markers in #1155/#1152): MKL's
Intel Fortran runtime installs a console CTRL handler that aborts the
whole backend (exit 2 / 0xC000013A) when a console CLOSE/LOGOFF event
reaches it. The backend was spawned with no console isolation, so OS
console events could reach it mid-session. Now:
- the desktop shell spawns the backend with CREATE_NO_WINDOW |
CREATE_NEW_PROCESS_GROUP (no console → no console events, stdio is
piped anyway) and sets FOR_DISABLE_CONSOLE_CTRL_HANDLER=1;
- backend/main.py setdefaults the same var before torch/numpy can load
MKL, covering scripts/run.sh and bare uvicorn launches too.
'charmap' codec can't encode (#1155): kittentts print()s the user's text
on every generate; on Windows the child's stdout is cp1252, so Vietnamese
text raised UnicodeEncodeError and surfaced as a bogus '400 Bad Request'.
The process-wide SafeFileWrapper only swallowed OSError (its EPIPE job).
Now:
- stdio is reconfigured to UTF-8 (errors=backslashreplace) at startup;
- SafeFileWrapper also swallows UnicodeError — logs are best-effort,
synthesis is not;
- the shell sets PYTHONUTF8=1 for the child (Windows→parity with
macOS/Linux; process env wins for power users);
- the crash-log append opens with encoding=utf-8 so tracebacks carrying
user text can't re-trip the same codec.
Regression tests: tests/test_windows_stdio_guards.py (cp1252 stream write
must not raise; main must set the Fortran guard + UTF-8 stdio).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Root cause: mcp_server._ensure_mcp() called sys.exit(1) when the mcp
import failed; SystemExit is a BaseException, so main.py's best-effort
'except Exception' around the /mcp mount never caught it and the whole
backend died with exit code 1 on startup.
- _ensure_mcp raises ImportError (catchable) with the underlying error —
the import can fail with the package present (broken pywin32 transitive
import on Windows), so 'not installed' was a misdiagnosis. The
standalone CLI keeps its exit(1) contract.
- New mcp_server.mount_mcp(app) contains Exception AND SystemExit at the
integration boundary (same exit-containment class as #1143's engine
boundary); main.py's mount guard catches SystemExit too.
- The 'Setup failed' splash card now auto-dismisses when the backend
becomes healthy: 'failed' used to stop the IPC poll loop while the
successful IPC reply had already disarmed the #879 HTTP watchdog, so
nothing could observe a recovered backend. A /health recovery poll now
runs for the failed stage (startHealthRecoveryPoll).
- Relaunching the app while bootstrap is Failed now retries the backend
spawn (same path as the Retry button) instead of just refocusing a dead
window (tauri single-instance callback).
Regression tests: tests/test_mcp_graceful_degradation.py (SystemExit →
ImportError, mount containment, CLI exit contract) and
frontend/src/test/BootstrapSplashFailedRecovery.test.jsx (failed → ready
on health, stays failed while dead).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Follows the existing speckit-* precedent: skill dirs are ignored by default,
and skills meant to ship with the repo (omnivoice) are re-negated explicitly.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
#1088 shipped a user-facing feature with no CHANGELOG entry, which the
release-notes rule forbids — release.yml extracts the section verbatim as the
GitHub Release body, so it would have shipped without its headline feature.
Backfilled in house style ahead of the v0.3.19 freeze.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>