OmniVoice-Studio / docs /STRUCTURE.md
LΓͺ Phi Nam
Deploy to HF Space
94004a2
|
Raw
History Blame Contribute Delete
8.71 kB

Project Structure

Every folder has a single job. Every file at the root earns its place.

Layout

OmniVoice/
β”‚
β”œβ”€β”€ README.md                    ⟡ user-facing overview
β”œβ”€β”€ CHANGELOG.md                 ⟡ release history
β”œβ”€β”€ LICENSE
β”‚
β”œβ”€β”€ pyproject.toml               ⟡ Python project manifest
β”œβ”€β”€ uv.lock                      ⟡ Python lockfile
β”œβ”€β”€ package.json                 ⟡ monorepo manifest (Bun workspaces + Turborepo)
β”œβ”€β”€ bun.lock                     ⟡ JS lockfile
β”œβ”€β”€ turbo.json                   ⟡ turborepo pipeline
β”‚
β”œβ”€β”€ .dockerignore                ⟡ Docker build context filter
β”œβ”€β”€ backend.spec                 ⟡ pyinstaller spec (stays at root by pyinstaller convention)
β”œβ”€β”€ alembic.ini                  ⟡ DB migration config (stays at root by alembic convention)
β”‚
β”œβ”€β”€ .env                         ⟡ user config; gitignored, .env.example is the template
β”œβ”€β”€ .gitignore
β”‚
β”œβ”€β”€ backend/                     ⟡ FastAPI server
β”‚   β”œβ”€β”€ main.py
β”‚   β”œβ”€β”€ api/routers/             HTTP endpoints (thin)
β”‚   β”œβ”€β”€ core/                    config, db, task queue, metrics
β”‚   β”œβ”€β”€ services/                business logic
β”‚   └── schemas/                 pydantic request/response shapes
β”‚
β”œβ”€β”€ frontend/                    ⟡ React 19 + Vite + Tauri desktop
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ pages/               one file per top-level view
β”‚   β”‚   β”œβ”€β”€ components/          reusable UI
β”‚   β”‚   β”œβ”€β”€ api/                 typed API clients
β”‚   β”‚   β”œβ”€β”€ store/               Zustand slices
β”‚   β”‚   β”œβ”€β”€ hooks/               custom React hooks
β”‚   β”‚   └── utils/
β”‚   β”œβ”€β”€ src-tauri/               Rust desktop shell
β”‚   └── public/
β”‚
β”œβ”€β”€ omnivoice/                   ⟡ the underlying TTS model package
β”‚   β”œβ”€β”€ models/
β”‚   β”œβ”€β”€ cli/                     CLI entry points (omnivoice-infer, etc.)
β”‚   β”œβ”€β”€ data/                    data utilities used by the model
β”‚   β”œβ”€β”€ eval/                    evaluation scripts
β”‚   β”œβ”€β”€ scripts/                 one-off utilities that ship with the package
β”‚   β”œβ”€β”€ training/
β”‚   └── utils/
β”‚
β”œβ”€β”€ tests/                       ⟡ all tests live here, no exceptions
β”‚   β”œβ”€β”€ conftest.py
β”‚   β”œβ”€β”€ test_api.py
β”‚   β”œβ”€β”€ test_dub_*.py
β”‚   β”œβ”€β”€ test_job_queue.py
β”‚   β”œβ”€β”€ test_segmentation.py
β”‚   └── frontend/                Node-based frontend tests
β”‚
β”œβ”€β”€ scripts/                     ⟡ dev / build / release shell + python scripts
β”‚   β”œβ”€β”€ install.sh               universal installer
β”‚   β”œβ”€β”€ run.sh                   universal launcher
β”‚   β”œβ”€β”€ smoke-test.sh            end-to-end validation
β”‚   └── desktop-prod.sh          production desktop build
β”‚
β”œβ”€β”€ deploy/                      ⟡ Docker deployment configs
β”‚   β”œβ”€β”€ Dockerfile               single-stage CUDA image
β”‚   └── docker-compose.yml       one-click local deployment
β”‚
β”œβ”€β”€ docs/                        ⟡ developer docs, screenshots, branding
β”‚   β”œβ”€β”€ ROADMAP.md               where this project is going
β”‚   β”œβ”€β”€ STRUCTURE.md             you are here
β”‚   β”œβ”€β”€ mcp.json                 MCP config template
β”‚   β”œβ”€β”€ preview.png              README hero image
β”‚   β”œβ”€β”€ logo.png, logo.svg       branding assets
β”‚   β”œβ”€β”€ screenshot-*.png         feature screenshots
β”‚   β”œβ”€β”€ languages.md
β”‚   β”œβ”€β”€ training.md
β”‚   β”œβ”€β”€ data_preparation.md
β”‚   β”œβ”€β”€ evaluation.md
β”‚   └── voice-design.md
β”‚
β”œβ”€β”€ design/                      ⟡ ASCII mockups of the target UX
β”‚   β”œβ”€β”€ README.md
β”‚   └── 00–08-*.md               per-feature specs
β”‚
β”œβ”€β”€ research/                    ⟡ reference material, competitor analysis, archived code
β”‚   β”œβ”€β”€ LEARNINGS.md             competitive analysis, what to absorb
β”‚   β”œβ”€β”€ TheWhisper/              vendored reference (read-only)
β”‚   β”œβ”€β”€ voice-pro/               vendored reference
β”‚   └── legacy_gradio/           archived Gradio UI (pre-React rewrite)
β”‚
β”œβ”€β”€ examples/                    ⟡ runnable demos + sample inputs
β”‚
β”œβ”€β”€ omnivoice_data/              ⟡ Docker bind-mount target (gitignored)
β”‚                                   DB + HF cache live here when running via compose
β”‚
└── .git/

Rules of the root

  1. Nothing at the root is a runtime artifact. Outputs, temp files, local DBs, crash logs β€” all go to ~/Library/Application Support/OmniVoice/ (or the OS equivalent), never into the repo. The one exception is omnivoice_data/, which exists as a bind-mount anchor for Docker.

  2. No ad-hoc scripts at the root. One-off debug scripts live in scripts/. Tests live in tests/. Benchmarks live in scripts/benchmarks/ (when we create them).

  3. Each subdirectory owns one concern. If you can't describe what goes in a directory in one sentence, it's wrong.

  4. Every package has a manifest. backend/, frontend/, omnivoice/ each have their own deps declared via pyproject.toml / package.json β€” they are independently testable.

What lives where

Kind of thing Goes in
User-facing product code backend/, frontend/
The TTS model (independent of the studio) omnivoice/
Everything executable but not user-facing scripts/
Tests tests/
Developer + user docs (Markdown) docs/
Target-state mockups design/
Competitor clones, legacy code, ref material research/
Runnable demos and sample data examples/
Runtime data (never committed) ~/Library/Application Support/OmniVoice/ on Mac

What doesn't live at the root anymore

Removed in the cleanup pass:

File Why it was there Where it went
test_crash.py, test_server.py, test_whisper.py, test_mock.py, test_pyannote.py One-off debug scripts from an April 14 crash investigation. Imported symbols that no longer exist after the router refactor. Deleted (already gitignored, referenced dead code).
benchmark.py Another stale debug script; imported backend.main._get_db which no longer exists. Deleted.
output.wav, test.wav Runtime artifacts. Deleted / moved out.
crash_log.txt Runtime log. Now written to $DATA_DIR/crash_log.txt. Deleted.
omnivoice.zip (148 MB) Offline reference archive of the project itself. Moved out of the repo to ../omnivoice.zip.bak.
data/ Only contained .DS_Store. Deleted.
legacy_gradio/ The pre-React Gradio UI. Kept for historical reference. Archived to research/legacy_gradio/.
Scattered .DS_Store files macOS Finder droppings. Deleted from every non-ignored directory.

Scaling path (proposed, not yet executed)

The current flat layout works fine for the current size. If the project grows to include additional apps (a mobile companion, a plugin SDK, multiple backends), migrate to a Turborepo-style monorepo:

OmniVoice/
β”œβ”€β”€ apps/
β”‚   β”œβ”€β”€ api/                 ← was backend/
β”‚   β”œβ”€β”€ web/                 ← was frontend/
β”‚   └── desktop/             ← could extract src-tauri/ here later
β”œβ”€β”€ packages/
β”‚   β”œβ”€β”€ omnivoice-model/     ← was omnivoice/
β”‚   └── tts-adapters/        ← new; the pluggable TTS interface from ROADMAP phase 3
β”œβ”€β”€ config/
β”‚   β”œβ”€β”€ docker/
β”‚   └── pyinstaller/
β”œβ”€β”€ tests/
β”œβ”€β”€ docs/
β”œβ”€β”€ design/
└── research/

Do not execute this migration without a dedicated PR. It breaks:

  • pyproject.toml [tool.hatch.build.targets.{sdist,wheel}] paths
  • package.json workspaces and scripts
  • turbo.json, Dockerfile, docker-compose.yml paths
  • backend.spec (['backend/main.py'], pathex=['.'])
  • frontend/src-tauri/tauri.*.conf.json sidecar paths
  • every import that reads from backend.main import … (tests, scripts)

Migrate when adding the second apps/* or the second packages/*. Not before.

Conventions

  • Filenames: snake_case for Python, kebab-case or PascalCase for JS/TS components, lowercase for Markdown.
  • Tests mirror source paths. backend/services/dub_pipeline.py β†’ tests/services/test_dub_pipeline.py.
  • One-off scripts go into scripts/ with a descriptive name, not test_*.py at the root.
  • New top-level directories require a PR that updates this file.