20 Commits
Author SHA1 Message Date
debpalashandClaude Opus 5 f259a3481f docs(changelog): record the PocketTTS engine (#1306, #1328)
#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>
2026-08-05 01:16:47 +05:30
mergetestandClaude Fable 5 5a6d4b1f5e docs(changelog): add the #1162/#1161 fixes to [Unreleased]
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 18:29:17 +05:30
mergetestandClaude Fable 5 532eb9fb2e docs(readme-cn): full retranslation — sync with the current English README
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 17:40:51 +05:30
mergetestandClaude Fable 5 6332a9c846 docs(readme-cn): mirror today's README refresh into the Chinese translation
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 17:24:05 +05:30
mergetestandClaude Fable 5 081890888b docs(readme): give the maker's other apps their due — logos, details, and a sponsor-section cross-link
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>
2026-07-16 17:07:51 +05:30
mergetestandClaude Fable 5 2d7d353a93 docs(readme): tighter, kinder to new users
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>
2026-07-16 16:51:22 +05:30
mergetestandClaude Fable 5 b17df5c7a3 docs(docker): refresh the Docker Hub overview and docker guide
- 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>
2026-07-16 16:41:40 +05:30
mergetestandClaude Fable 5 f609f57fbc chore(release): codify all deployment channels as release rules; preview always builds from main
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>
2026-07-16 16:12:31 +05:30
mergetestandClaude Fable 5 060d826f3c docs(changelog): add the #1159/#1160/#1158 fixes to [Unreleased]
#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>
2026-07-16 16:11:53 +05:30
mergetestandClaude Fable 5 025a358a58 docs(event-bus): document the single-loop no-await invariant in _broadcast (#1163)
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>
2026-07-16 16:11:02 +05:30
b9c677db2c fix(frontend): log swallowed data-loading failures in useAppData (absorbed from #1158)
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>
2026-07-16 16:10:41 +05:30
mergetestandClaude Fable 5 5b74627e78 fix(backend): stop discarding tracebacks in error-level exception logs (#1160 follow-up)
#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>
2026-07-16 16:10:06 +05:30
mergetestandClaude Fable 5 577fe5aa3c test(bootstrap): render regression test for the stage="failed" TDZ crash (#1159)
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>
2026-07-16 16:06:08 +05:30
mergetestandClaude Fable 5 42ad806cdb docs(changelog): add the #1156/#1153/#1155/#1152 fixes to [Unreleased]
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 01:45:55 +05:30
mergetestandClaude Fable 5 155cebe911 fix(dub): diagnose export failures honestly; dodge the Windows 32K argv limit (#1152)
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>
2026-07-16 01:45:23 +05:30
mergetestandClaude Fable 5 a601db8448 fix(win): stop the Fortran-runtime console-close abort and cp1252 UnicodeEncodeError crash classes (#1153, #1155)
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>
2026-07-16 01:45:23 +05:30
mergetestandClaude Fable 5 9ff394a48b fix(backend,shell): a missing MCP SDK can no longer kill the backend — and a failed setup now self-heals (#1156)
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>
2026-07-16 01:45:00 +05:30
mergetestandClaude Fable 5 ebdbb10921 chore(gitignore): ignore locally-installed third-party skill packs under .claude/skills/
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>
2026-07-16 01:03:36 +05:30
mergetestandClaude Fable 5 2bda4ff580 docs(changelog): start [Unreleased] with the #1154 remote-auth API-key gate fix
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 00:59:44 +05:30
mergetestandClaude Fable 5 127681396e docs(changelog): backfill the streaming-TTS-preview entry (#1088)
#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>
2026-07-12 12:15:50 +05:30