Spaces:
Sleeping
Sleeping
| # 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*. | |