v0.2.0: System tray, IPC status, VAD, hotkey grab, and polish

- Add system tray icon with Exit menu (tray-icon/muda)
- Add IPC daemon status via named pipe (Windows) / Unix socket (Linux)
- Add `mouth status` command to query running daemon
- Add daemon lock to prevent multiple instances
- Hide Windows console window when running as daemon
- Wire up Silero VAD model download and speech filtering
- Switch hotkey listener from rdev::listen to rdev::grab to consume hotkeys
- Add hotkey capture mode in interactive config (press keys instead of typing)
- Add all missing key names (brackets, punctuation, numpad, etc.)
- Fix ONNX tensor type mismatches (encoder wants i64, decoder wants i32)
- Add 300ms lead-in silence to compensate for mic startup latency
- Add 300ms trailing recording after stop for speech not to be clipped
- Add 50ms silence before audio feedback blips for device warmup
- Reduce overlay size (150x18, was 200x36)
- Add PolyForm Noncommercial 1.0.0 license
- Flesh out user-focused README
- Update release script with Gitea/GitHub forge support

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-10 22:04:39 +01:00
parent f9d65ff850
commit 0cea6a4b28
19 changed files with 1948 additions and 490 deletions
+35
View File
@@ -0,0 +1,35 @@
use std::sync::RwLock;
use std::time::Instant;
/// Thread-safe shared state accessible by the coordinator, IPC listener, and tray icon.
pub struct SharedState {
pub state: RwLock<String>,
pub model: String,
pub accelerator: String,
pub started_at: Instant,
}
impl SharedState {
pub fn new(model: String, accelerator: String) -> Self {
Self {
state: RwLock::new("idle".to_string()),
model,
accelerator,
started_at: Instant::now(),
}
}
pub fn set_state(&self, state: &str) {
if let Ok(mut s) = self.state.write() {
*s = state.to_string();
}
}
pub fn get_state(&self) -> String {
self.state.read().map(|s| s.clone()).unwrap_or_else(|_| "unknown".to_string())
}
pub fn uptime_secs(&self) -> u64 {
self.started_at.elapsed().as_secs()
}
}