# CLAUDE.md - LocalVoiceMode v2
## Project Overview
Hybrid voice interface: **Rust GUI** (egui + wgpu) + **Python ML Server** (TTS/ASR/SER).
Location: `C:\AI\localvoicemode\v2`
## Quick Commands
```bash
# Rust GUI
cd voicemode-ui && cargo run --release
# Python ML Server
cd ml-server && python -m ml_server
# Run both (from v2/)
cargo run --release --manifest-path voicemode-ui/Cargo.toml &
python -m ml_server
```
## Architecture
```
voicemode-ui (Rust) ml-server (Python)
┌─────────────────┐ ┌─────────────────┐
│ egui + wgpu │◄────────►│ Model Registry │
│ Audio (cpal) │ JSON-RPC │ TTS/ASR/SER │
│ VAD (ONNX) │ │ LLM Client │
└─────────────────┘ └─────────────────┘
```
## Key Files
### Rust Side
- `voicemode-ui/src/main.rs` - Entry point
- `voicemode-ui/src/app.rs` - Main App struct
- `voicemode-ui/src/ui/waveform.rs` - Visualizer
- `voicemode-ui/src/ui/theme.rs` - Color palette
- `voicemode-ui/assets/shaders/bloom.wgsl` - Glow effect
### Python Side
- `ml-server/ml_server/main.py` - Server entry
- `ml-server/ml_server/models/tts/base.py` - TTS Protocol
- `ml-server/ml_server/registry/tts_registry.py` - Model registry
- `ml-server/ml_server/ipc/server.py` - JSON-RPC handler
## IPC Protocol
```json
// Transcribe audio
{"jsonrpc":"2.0","id":1,"method":"transcribe","params":{"audio_b64":"..."}}
// Result with emotion
{"jsonrpc":"2.0","id":1,"result":{"text":"Hello","emotion":"happy"}}
// Speak text
{"jsonrpc":"2.0","id":2,"method":"speak","params":{"text":"Hi","voice":"hermione"}}
// Streamed audio chunks
{"jsonrpc":"2.0","method":"audio_chunk","params":{"chunk_b64":"...","final":false}}
```
## Color Palette
| Name | Hex | RGB | Use |
|------|-----|-----|-----|
| Lapis Lazuli | #2659A5 | (38,89,165) | Listening |
| Mace Windu | #8033CC | (128,51,204) | Processing |
| Emerald | #33B24D | (51,178,77) | Speaking |
| Burnt Orange | #CC661A | (204,102,26) | Warning |
| Sith Red | #E61A1A | (230,26,26) | Error |
## Model Interfaces
All models implement a Protocol:
```python
class TTSModel(Protocol):
def synthesize(self, text: str, voice: str, emotion: str | None) -> np.ndarray: ...
def synthesize_streaming(self, ...) -> Iterator[np.ndarray]: ...
```
Register models:
```python
@TTSRegistry.register("pocket")
class PocketTTSAdapter:
...
```
## Development Workflow
1. Make changes to Rust or Python
2. Restart the affected process
3. Test via the GUI or CLI tools
## Testing
```bash
# Rust tests
cd voicemode-ui && cargo test
# Python tests
cd ml-server && pytest
# Integration test
python -m ml_server.test_client
```
## Debugging
- Rust logs: `RUST_LOG=debug cargo run`
- Python logs: `LOG_LEVEL=DEBUG python -m ml_server`
- IPC tracing: Set `IPC_TRACE=1` to log all messages
## Common Tasks
### Add a New TTS Model
1. Create `ml-server/ml_server/models/tts/mymodel.py`
2. Implement `TTSModel` Protocol
3. Register with `@TTSRegistry.register("mymodel")`
4. Add to settings UI in Rust
### Change Waveform Colors
Edit `voicemode-ui/src/ui/theme.rs` - modify `VoiceModeTheme::default()`
### Adjust Bloom Intensity
Edit `voicemode-ui/assets/shaders/bloom.wgsl` - modify `glow_intensity`