diff --git a/README.md b/README.md index 3ece571..3abee67 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,49 @@ -# Kithara Studio +# 🎡 Kithara Studio -A webapp for generating, playing, and storing music clips using Google's Lyria music generation models. +A self-hosted webapp for generating, playing, and managing music clips using Google's Lyria music generation models. -Built by Kagamine Rin & Ryan. +Built by [Kagamine Rin](https://rin.captcouch.xyz) & Ryan. + +> **⚠️ Under Active Development** +> Kithara Studio is pre-1.0 software under rapid development. Features change, APIs shift, and things break. We use it daily and it works for us, but expect rough edges. Issues and feedback are welcome β€” PRs are welcome too if you're into that sort of thing. + +--- + +## Features + +- **Music Generation** β€” Generate clips from text prompts using Google's Lyria models (currently Lyria 3 Clip Preview) +- **Structured Prompts** β€” Build prompts with genre, mood, instrumentation, and description fields +- **Maestro Mode** β€” Visual playback animation with cycling musical notes +- **Audio Player** β€” Stream MP3 playback with waveform visualization +- **Metadata & ID3 Tags** β€” Auto-detect BPM and key; set artist, album, genre, and comment; embed cover art and tags on download +- **Artwork Generation** β€” AI-generated cover art via Gemini +- **Favorites** β€” Heart clips to pin them (DB-backed, multi-user ready) +- **Dark Theme** β€” Purpose-built dark UI for late-night production sessions +- **Multi-User Auth** β€” Optional JWT auth with invite codes (single-user mode by default) +- **Admin CLI** β€” `kithara-admin` for user management from the command line +- **Docker Ready** β€” Full Docker Compose setup with Nginx reverse proxy + +--- ## Quick Start +### Docker (Recommended) + +```bash +# Clone and configure +git clone https://github.com/your-org/kithara-studio.git +cd kithara-studio +cp .env.example .env +# Edit .env β€” set your LYRIA_API_KEY + +# Launch +docker compose up -d --build + +# Open http://localhost:3100 +``` + +### Manual (Development) + ```bash # Backend cd backend @@ -13,37 +51,179 @@ python -m venv .venv source .venv/bin/activate pip install -r requirements.txt cd src -uvicorn main:app --reload +uvicorn main:app --reload --port 8000 # Frontend (new terminal) cd frontend npm install npm run dev +# Open http://localhost:5173 ``` -## Architecture +--- -- **Backend**: FastAPI (Python) β€” async API client for Google's Lyria models, SQLite metadata, file storage -- **Frontend**: React + Vite + TypeScript + Tailwind β€” dark theme, audio player -- **Storage**: SQLite for clip metadata, local filesystem for MP3 files +## Configuration + +All configuration is via environment variables (`.env` file): + +| Variable | Default | Description | +|----------|---------|-------------| +| `LYRIA_API_KEY` | *(required)* | Google Lyria API key | +| `LYRIA_DEFAULT_MODEL` | `lyria-3-clip-preview` | Default Lyria model | +| `KITHARA_MODE` | `single` | `single` = no auth, `multi` = JWT auth required | +| `KITHARA_ADMIN_USER` | `admin` | Bootstrap admin username (multi mode) | +| `KITHARA_ADMIN_PASS` | `admin` | Bootstrap admin password (multi mode) | +| `DEFAULT_ID3_ARTIST` | `Kagamine Rin` | Default artist tag | +| `DEFAULT_ID3_ALBUM` | `Kithara Studio` | Default album tag | +| `DEFAULT_ID3_GENRE` | `Hardcore Techno` | Default genre tag | +| `TZ` | `America/New_York` | Timezone | + +### Authentication Modes + +**Single-user mode** (`KITHARA_MODE=single`) β€” No login required. All clips belong to a default user. Best for personal use or trusted networks. + +**Multi-user mode** (`KITHARA_MODE=multi`) β€” JWT authentication required. Users register with invite codes. Admin user is bootstrapped on first startup. Best for shared deployments. + +--- + +## Admin CLI + +Manage users and invite codes from the host: + +```bash +# List users +python3 kithara-admin list-users + +# Create a user +python3 kithara-admin create-user alice --password secret --role user + +# Create an invite code +python3 kithara-admin create-invite +python3 kithara-admin create-invite --max-uses 5 + +# List invite codes +python3 kithara-admin list-invites + +# Change role +python3 kithara-admin change-role alice admin + +# Reset password +python3 kithara-admin reset-password alice newpass123 + +# Delete user (requires --confirm) +python3 kithara-admin delete-user alice --confirm + +# Revoke invite code +python3 kithara-admin revoke-invite CODE_HERE +``` + +> **Note:** The CLI reads `data/kithara.db` directly. If running in Docker, ensure the database file is writable by your host user, or run the CLI with appropriate permissions. + +--- ## API | Endpoint | Method | Description | |----------|--------|-------------| -| `/api/health` | GET | Health check | -| `/api/generate` | POST | Start clip generation | -| `/api/clips` | GET | List all clips | -| `/api/clips/{id}` | GET | Get clip metadata | -| `/api/clips/{id}/audio` | GET | Stream MP3 | -| `/api/clips/{id}` | DELETE | Delete clip | +| `GET /api/health` | β€” | Health check (includes mode: single/multi) | +| **Clips** | | | +| `POST /api/generate` | β€” | Start clip generation | +| `GET /api/clips` | β€” | List clips | +| `GET /api/clips/{id}` | β€” | Clip metadata | +| `GET /api/clips/{id}/audio` | β€” | Stream MP3 | +| `PATCH /api/clips/{id}` | β€” | Update clip (title, metadata) | +| `DELETE /api/clips/{id}` | β€” | Delete clip | +| `POST /api/clips/{id}/favorite` | β€” | Toggle favorite | +| **Artwork** | | | +| `PATCH /api/clips/{id}/artwork` | β€” | Upload cover art | +| `DELETE /api/clips/{id}/artwork` | β€” | Remove cover art | +| `POST /api/clips/{id}/generate-artwork` | β€” | AI-generate cover art | +| **Analysis** | | | +| `GET /api/clips/{id}/analysis` | β€” | BPM and key detection | +| **Auth** (multi mode) | | | +| `POST /api/auth/login` | β€” | Login (returns JWT) | +| `POST /api/auth/register` | β€” | Register (requires invite code) | +| `GET /api/auth/me` | β€” | Current user info | +| `PUT /api/auth/api-key` | β€” | Set per-user Lyria API key | +| **Admin** (multi mode) | | | +| `GET /admin/users` | β€” | List users | +| `POST /admin/users` | β€” | Create user | +| `DELETE /admin/users/{id}` | β€” | Delete user | +| `PUT /admin/users/{id}/role` | β€” | Change user role | +| `POST /admin/invites` | β€” | Create invite code | +| `GET /admin/invites` | β€” | List invite codes | +| `DELETE /admin/invites/{code}` | β€” | Revoke invite code | + +--- + +## Architecture + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Nginx │────▢│ FastAPI │────▢│ SQLite β”‚ +β”‚ (reverse β”‚ β”‚ Backend β”‚ β”‚ (data/) β”‚ +β”‚ proxy) β”‚ β”‚ :8000 β”‚ β”‚ β”‚ +β”‚ :3000 β”‚ β”‚ β”‚ β”‚ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ β”‚ + β”‚ β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ Lyria β”‚ + β”‚ β”‚ API β”‚ + β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ +β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β” +β”‚ React + β”‚ +β”‚ Vite + TS β”‚ +β”‚ Tailwind β”‚ +β”‚ (SPA) β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +- **Backend**: FastAPI (Python) β€” async API client for Google's Lyria models, SQLite metadata, file storage, JWT auth +- **Frontend**: React + Vite + TypeScript + Tailwind β€” dark theme SPA with audio player and waveform visualization +- **Storage**: SQLite for clip metadata + user data, local filesystem for MP3 files and cover art +- **Auth**: JWT tokens (multi-user mode), bcrypt password hashing, invite-based registration + +--- ## Models -- **v0.1**: Google Lyria 3 Clip Preview (30s, REST) -- **v0.2**: Google Lyria 3 Pro (structure-aware, ~3min) -- **v0.3**: Google Lyria RealTime (WebSocket streaming) +| Version | Model | Duration | Status | +|---------|-------|----------|--------| +| v0.1 | Lyria 3 Clip Preview | ~30s | βœ… Active | +| v0.2 | Lyria 3 Pro | ~3min | πŸ”œ Planned | +| v0.3 | Lyria RealTime | Streaming | πŸ”œ Planned | + +--- + +## Roadmap + +This is Phase 1 of a multi-phase roadmap: + +- [x] **Phase 1** β€” Users & Auth, `KITHARA_MODE` switch, admin CLI +- [ ] **Phase 2** β€” Data isolation (per-user clip scoping) +- [ ] **Phase 3** β€” Per-user Lyria API keys (BYOK) +- [ ] **Phase 4** β€” Community gallery (sharing, discovery) +- [ ] **Phase 5** β€” Remix (fork clips into new generations) +- [ ] **Phase 6** β€” Email notifications (optional) + +--- + +## Development + +```bash +# Run tests (requires librosa, librosa dependencies) +cd backend +pip install -r requirements.txt +pytest tests/ -v + +# Type check frontend +cd frontend +npx tsc --noEmit +``` + +--- ## License -MIT β€” Hardcore will never die. +MIT β€” Hardcore will never die. 🎡 \ No newline at end of file