Files
VoiceStudio/CLAUDE.md
T
a0ad314736 docs: CLAUDE.md refresh — de-rot versions, compress shipped stack research, replace the dead GSD gate (#1025)
Three classes of staleness that actively misled agent sessions:

- The Project section hardcoded "latest stable v0.3.5 / main at v0.3.6"
  — eight releases behind. Now points at the sources of truth
  (frontend/package.json, the Releases page) and documents the current
  AUTO_VERSION_BUMP-off holding behavior instead of a version literal
  that rots every release.
- ~165 lines of May-2026 stack research for five capabilities that have
  ALL since shipped (HF-token panel, prefilled-URL bug reporting, uv
  mirror fallback, Supertonic-3, in-repo docs). Compressed to the
  durable don'ts it established (no telemetry endpoints, no app-side
  GitHub tokens, no setx, no MkDocs, no hf_transfer) plus a pointer to
  prefer what's already pinned.
- The GSD Workflow Enforcement gate referenced /gsd-quick//gsd-debug/
  /gsd-execute-phase skills that exist nowhere in this environment; the
  owner explicitly chose direct edits over restoring them (2026-07-08).
  It cost a real mid-task detour when a subagent correctly refused to
  work under an unsatisfiable rule. Replaced with the owner decision
  and the working conventions that actually bind (merge gating,
  check-the-PR-queue-first).

244 → 83 lines. GSD section markers preserved so the generating tool
can still find its blocks.

Co-authored-by: mergetest <test@local>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 04:25:14 +05:30

13 KiB
Raw Blame History

Project

OmniVoice Studio

OmniVoice Studio is an open-source, fully-local ElevenLabs alternative — a desktop app for voice cloning, voice design, video dubbing, and real-time dictation across 646 languages. It runs entirely on the user's machine (CUDA/MPS/ROCm/CPU auto-detect), with no API keys, no accounts, and no cloud dependencies. It's an active beta with a growing user base who hit it with real workloads (50-video batches, multi-engine setups, edge-OS platforms) and report friction in GitHub Issues and Discord. The current version lives in frontend/package.json (the single source of truth — see Versioning); the latest stable tag is on the Releases page. With AUTO_VERSION_BUMP off (the current owner setting), main holds at the released version between releases.

Core Value: A first-run that actually works. A user who downloads the installer (or clones the repo) should reach a working voice-cloning or dubbing output without hitting a wall — and when something does go wrong, the error or docs should tell them exactly what to do.

Everything else (new engines, fancy features) is downstream of "the thing installs and runs reliably across platforms, with the engines and pipelines users already depend on staying compatible."

Constraints

  • Existing engine compatibility: Users with already-installed engines (IndexTTS, CosyVoice, etc.) must not have to reinstall. Fixes touching engine code must be backward-compatible with on-disk model state.
  • Cross-platform parity: Every fix must work on macOS (Apple Silicon + Intel), Windows (x64), and Linux (AppImage + deb). No platform-only regressions; the cross-platform bug bash (PR #51) is the baseline.
  • Default features must work on every platform (strict rule, 2026-05-20): A feature that ships in default mode — out-of-the-box, no user customization, no opt-in toggle — must behave identically on macOS, Windows, and Linux. Platform-specific implementation code is allowed for OS APIs / shells / packaging, but the user-visible default behavior cannot diverge. Platform-only features (e.g., a macOS-only global shortcut, a Windows-only path picker) must go behind explicit user opt-in: Settings toggle, env var, or CLI flag. When a default doesn't work on a platform, that's a P0 bug — either fix it on the missing platform or move it behind opt-in. No third option.
  • Backward-compatible project data: Existing omnivoice_data/ (user voices, projects, settings) must keep working without manual migration. Any DB schema change goes through alembic with a tested upgrade path.
  • Local-first guarantee preserved: Auto bug reporting (new addition) must be opt-in, must submit only to GitHub Issues (no third-party telemetry endpoint), and the app must remain fully functional with reporting disabled. No required cloud calls, accounts, or API keys.
  • Beta release cadence (no RC, no ceremony — strict rule, 2026-05-20): the v0.3.x line has no release candidates, no 48h soak, no formal release ceremony. Every fix goes continuous-to-main; the owner tags a patch (v0.3.Z) from main whenever the current state is worth cutting. No -rc tags. No phased release. No v0.4 deferrals while the v0.3.x line is open — every open issue and every open community PR gets absorbed into the v0.3.x line or explicitly declined. Users follow main for previews; users wanting stable stay on the latest tagged release. ROADMAP.md's Phase 6 "Release/Verify/Retro" entries are obsolete unless the user revives them.

Technology Stack

The May-2026 stack research that used to live here served five capabilities that have all since shipped (HF-token Settings panel, prefilled-URL bug reporting, uv mirror fallback for restricted networks, the Supertonic-3 engine, in-repo Markdown docs). Follow the patterns in the code itself; the durable don'ts that research established:

  • No third-party telemetry endpoints, ever (sentry-tauri was evaluated and rejected) — bug reporting stays opt-in via prefilled GitHub-issue URLs.
  • No PAT/token-based GitHub posting from the app — the user submits from their own browser.
  • Don't recommend setx for env vars on Windows (silent truncation, no current-shell propagation) — use the in-app Settings panel or PowerShell [Environment]::SetEnvironmentVariable.
  • Don't adopt Material for MkDocs for any future docs site (maintenance mode since Nov 2025) — Astro Starlight is the precedent if docs ever outgrow the repo.
  • hf_transfer is deprecated — default huggingface_hub (hf-xet) handles downloads.

For anything new: prefer what's already pinned in pyproject.toml / frontend/package.json, and check uv tree for conflicts before adding a dependency.

Conventions

Versioning (hard rule, owner-set 2026-06-11; single-source 2026-06-16): main is always latest release + 1 patch. frontend/package.json is the SINGLE SOURCE OF TRUTH for the app version — vite injects __APP_VERSION__ from it (first-run footer + every auto bug report), and frontend/src-tauri/tauri.conf.json reads its bundle version from it ("version": "../package.json", so the MSI/dmg/updater version can't drift from the UI). Three toolchain-required mirrors are kept equal to it and bumped in lockstep — frontend/src-tauri/Cargo.toml + pyproject.toml (cargo/uv need a literal) and backend/core/version.py's _FALLBACK_VERSION (the frozen-backend last resort; at runtime the backend reads its version from package metadata via importlib.metadata, which backend.spec's copy_metadata('omnivoice') makes work in the frozen build too). Never hand-edit any mirror or re-hardcode a literal in tauri.conf.json. Guarded by tests/test_app_version.py (test_all_version_files_in_lockstep + test_tauri_version_derives_from_package_json). The moment vX.Y.Z is released, bump package.json (+ the mirrors) to X.Y.(Z+1). Consequences:

  • Every PR and preview build identifies as the next version. Preview builds stamp X.Y.(Z+1)-N (run number), which semver-sorts above the last stable X.Y.Z — the updater ordering is natural, no comparator tricks needed.
  • Releasing = tag vX.Y.(Z+1) from main (version files already match), then immediately bump main to X.Y.(Z+2). Owner override (2026-07-01): the post-release bump is now MANUAL — the version-bump job in release.yml is opt-in behind the AUTO_VERSION_BUMP repo variable (default off), so main stays at the released version until the owner explicitly asks to bump. (Historically the bump auto-ran; re-enable that by setting AUTO_VERSION_BUMP=true.) When pinned, main == the released tag; preview-build ordering and "release + 1" only resume once a bump is requested.
  • Docker: ghcr.io/debpalash/omnivoice-studio:latest = main (rolling preview); :X.Y.Z + :X.Y + :stable = tagged releases. :latest is the preview channel by design — stable users pin :stable or a version tag.
  • Do not bump minor/major or invent RCs/codenames without the owner asking. No "defer to next version" labels — scope is absorbed or declined, never re-versioned.

Docs-sync (hard rule, owner-set 2026-06-11): any change that alters something these docs describe — README.md, CONTRIBUTING.md, SECURITY.md, SUPPORT.md, LICENSE, or docs/** (install flows, Docker tag semantics, platform support, versioning/release behavior, review process, supported versions) — must update those docs in the same PR as the change. If a doc impact is discovered after merge, the docs fix is the immediate next commit, not backlog. Stale docs are treated as bugs.

Release notes / changelog (hard rule, owner-set 2026-06-16): every tagged release gets a high-quality, user-facing ## [X.Y.Z] — DATE section in CHANGELOG.md before (or in the same hour as) the tag — never the "Auto-generated release for vX.Y.Z…" fallback. release.yml extracts that section verbatim as the GitHub Release body (the Extract CHANGELOG section for tag step), so a missing/empty section ships a bare release. Quality bar = the existing house style: a one-paragraph headline, then ### Added / ### Fixed / ### Changed / ### License / ### CI subsections; each entry is a bold one-line lead (what the user gets), 13 lines of plain-English why, and the (#NNN) issue/PR ref — grouped by theme, written for users, not raw commit dumps. This applies to preview builds too: preview release notes summarize what's new on main since the last stable, in the same style. Workflow: as features merge, keep ## [Unreleased] current; at release time rename it to the version + date. If a release was already cut with the fallback body, the next action is to backfill CHANGELOG.md and gh release edit <tag> the live body — not backlog.

Localization (hard rule): No hardcoded non-English (CJK) user-facing text anywhere in the codebase except the translation layer (frontend/src/i18n/). All UI strings go through i18n (t('...') keys in locales/*.json); native language names live in i18n/index.ts (LANGUAGES). Functional CJK is allowed and tracked via the allowlist in tests/test_no_hardcoded_cjk.py — text-processing regexes, model/engine vocabulary & identifiers (e.g. CosyVoice speaker IDs), localized error matching, demo/eval data, and test fixtures. CI fails on any hardcoded CJK outside the allowlist; to add legitimate functional CJK, extend _ALLOWED_FILES there with a justification.

Fix quality (hard rule, owner-set 2026-06-16): Fix issues properly and future-maintenance-proof — don't stop at the symptom. Root-cause fully, fix the whole class of the bug (not just the one reported instance), add a fail-before/pass-after regression test, and harden against recurrence (e.g. if a lockfile drift only fails in Docker, also make CI catch it). Go the extra mile where it durably pays off. Be token-efficient about it — extra effort, not extra verbosity: no padding, no redundant re-checks, the smallest correct change that is also recurrence-proof. Don't be shy to spend the effort a proper fix needs; do be shy about wasting tokens.

Keep main green (hard rule, owner-set 2026-06-16): A merge must never break main's CI. Before a change lands, verify the full CI matrix would pass — every workflow in .github/workflows/ and deploy/Dockerfile, not only the checks you happened to run. Dependency / lockfile / config changes must be validated against all consumers. Specifically: frontend/ is a bun workspace monorepo — the lockfile is the repo-root bun.lock, and deploy/Dockerfile runs bun install --frozen-lockfile, so any frontend/package.json change requires regenerating root bun.lock and confirming bun install --frozen-lockfile passes (plain bun install in ci.yml silently tolerates drift, so CI-green ≠ Docker-green). Likewise re-check CodeQL/Security on code changes and the Tauri cargo build on Rust/dep changes.

Other conventions not yet established. Will populate as patterns emerge during development.

Architecture

Architecture not yet mapped. Follow existing patterns found in the codebase.

Project Skills

No project skills found. Add skills to any of: .claude/skills/, .agents/skills/, .cursor/skills/, .github/skills/, or .codex/skills/ with a SKILL.md index file.

Workflow

Direct repo edits are authorized (owner decision, 2026-07-08). The GSD command gate that used to live here referenced /gsd-quick / /gsd-debug / /gsd-execute-phase skills that are not installed in this environment; the owner chose to keep working directly rather than restore them. The working conventions that matter are in Conventions above — versioning, docs-sync, changelog, localization, fix quality, keep-main-green — plus: gate every merge on the "Tests (backend + frontend)" check passing and the PR being MERGEABLE, and check the open-PR queue before implementing any community-reported fix (contributors may have already submitted one).

Developer Profile

Profile not yet configured. Run /gsd-profile-user to generate your developer profile. This section is managed by generate-claude-profile -- do not edit manually.