Tray + lifecycle: - tauri-plugin-single-instance — second launch focuses existing window instead of racing for port 3900. - Window close hides instead of destroying; backend shutdown moved to RunEvent::ExitRequested so only the tray "Quit" item (or Cmd+Q on macOS) actually exits. - Tray icon flips to red-dot variant during dictation recording. Hotkey customization: - Settings → Capture tab. Records any modifier+key combo, persists to app config, re-registers on launch. - set_dictation_shortcut rolls back to the previous binding on register failure so a bad combo never leaves the user with no shortcut. Dictation latency / correctness: - WS-final treated as source of truth; HTTP POST /transcribe runs only as fallback (WS error / timeout / no-WS path). Audio transcribed once instead of twice. Server accepts an "EOF" text frame (or empty binary frame) so the socket stays open for `final` to be delivered before the client closes. - MediaRecorder chunks queued during the WS handshake are drained in ws.onopen — the server's final transcript no longer drops the first ~250 ms of audio. - Fallback timeout scales with recording length (max(15s, recordedMs+10s)) so long-form dictations don't trip duplicate transcription. Donate page: - Drop Patreon, Bitcoin / Ethereum / Solana cards. Drop qrcode.react. - Move "Commercial License" CTA from page bottom to top-right header bar. Docker hygiene: - docker-compose binds 127.0.0.1 by default. README documents the LAN exposure trade-off + recommends a reverse proxy with auth. CI: - New cross-platform `tauri-cross-platform` job runs `cargo check` against the Tauri shell on macOS / Windows / Linux per PR. Catches platform cfg-gate regressions without paying the full ~15min/platform bundle cost (full bundling stays in release.yml on tag push). Tests: - tests/test_capture_ws.py (3 cases) covers EOF text-frame, empty-binary EOF, and legacy disconnect-finalize paths. Includes the user's previously-staged 0.2.5 polish: cross-platform desktop-prod.sh, Dockerfile base-image fix, bun.lock churn. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
72 lines
2.5 KiB
YAML
72 lines
2.5 KiB
YAML
# ──────────────────────────────────────────────────────────────
|
|
# OmniVoice Studio — Docker Compose
|
|
#
|
|
# Quick start:
|
|
# docker compose up # CPU mode
|
|
# docker compose --profile gpu up # NVIDIA GPU mode
|
|
#
|
|
# First run downloads ~4 GB of models. Progress is shown in logs.
|
|
# Open http://localhost:3900 once the health check passes.
|
|
#
|
|
# SECURITY: The port is bound to 127.0.0.1 by default — only this
|
|
# machine can reach the API. To expose OmniVoice on your LAN (or
|
|
# through a reverse proxy / tunnel), change the port mapping to
|
|
# "0.0.0.0:3900:3900" or "3900:3900". OmniVoice itself ships no
|
|
# authentication — if you expose it, put it behind a reverse proxy
|
|
# with auth (Caddy basic_auth, nginx + htpasswd, Tailscale, etc.).
|
|
# ──────────────────────────────────────────────────────────────
|
|
|
|
services:
|
|
# ── CPU mode (default) ──────────────────────────────────────
|
|
omnivoice:
|
|
build: .
|
|
container_name: omnivoice-studio
|
|
ports:
|
|
- "127.0.0.1:3900:3900"
|
|
volumes:
|
|
- omnivoice-data:/app/omnivoice_data
|
|
environment:
|
|
- HF_HOME=/app/omnivoice_data/huggingface
|
|
- HF_TOKEN=${HF_TOKEN:-}
|
|
- OMNIVOICE_DATA_DIR=/app/omnivoice_data
|
|
- PYTHONUNBUFFERED=1
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-sf", "http://localhost:3900/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 120s
|
|
restart: unless-stopped
|
|
|
|
# ── GPU mode — activate with: docker compose --profile gpu up
|
|
omnivoice-gpu:
|
|
build: .
|
|
container_name: omnivoice-studio-gpu
|
|
profiles: ["gpu"]
|
|
ports:
|
|
- "127.0.0.1:3900:3900"
|
|
volumes:
|
|
- omnivoice-data:/app/omnivoice_data
|
|
environment:
|
|
- HF_HOME=/app/omnivoice_data/huggingface
|
|
- HF_TOKEN=${HF_TOKEN:-}
|
|
- OMNIVOICE_DATA_DIR=/app/omnivoice_data
|
|
- PYTHONUNBUFFERED=1
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-sf", "http://localhost:3900/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 180s
|
|
deploy:
|
|
resources:
|
|
reservations:
|
|
devices:
|
|
- driver: nvidia
|
|
count: 1
|
|
capabilities: [gpu]
|
|
restart: unless-stopped
|
|
|
|
volumes:
|
|
omnivoice-data:
|