mirror of
https://github.com/jamiepine/voicebox.git
synced 2026-09-16 13:20:39 -07:00
The pill window now surfaces for agent-initiated speech without main-window
involvement. Rust subscribes to /events/speak via a tokio task + reqwest
streaming body (speak_monitor.rs), shows the pill, and forwards events to
the dictate webview over Tauri's event bus. The pill plays audio via a
plain HTMLAudioElement and emits dictate:hide when playback ends. The
pill stays hidden through the ~1 s generation wait and only surfaces when
audio actually starts, with the counter armed at that moment.
Fixes a shared-dict mutation in mcp_server/events.publish() that caused
the second subscriber (Rust speak_monitor) to receive `event: message`
instead of named speak-start/speak-end frames. Also teaches the speak_monitor
parser to handle CRLF framing (sse-starlette default). Main-window
AudioPlayer now skips autoplay for source in {mcp, rest} to avoid
double-play when both windows are alive.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
64 lines
2.1 KiB
TOML
64 lines
2.1 KiB
TOML
[package]
|
|
name = "voicebox"
|
|
version = "0.5.0"
|
|
description = "A production-quality desktop app for Qwen3-TTS voice cloning and generation"
|
|
authors = ["you"]
|
|
license = ""
|
|
repository = ""
|
|
edition = "2021"
|
|
|
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
|
|
[build-dependencies]
|
|
tauri-build = { version = "2.0", features = [] }
|
|
|
|
[dependencies]
|
|
tauri = { version = "2.0", features = ["macos-private-api"] }
|
|
tauri-plugin-dialog = "2.0"
|
|
tauri-plugin-fs = "2.0"
|
|
tauri-plugin-shell = "2.0"
|
|
serde = { version = "1.0", features = ["derive"] }
|
|
serde_json = "1.0"
|
|
tokio = { version = "1", features = ["full"] }
|
|
reqwest = { version = "0.12", features = ["blocking", "json", "stream"] }
|
|
hound = "3.5"
|
|
base64 = "0.22"
|
|
cpal = "0.15"
|
|
symphonia = { version = "0.5", features = ["all"] }
|
|
scopeguard = "1.2.0"
|
|
|
|
[target.'cfg(target_os = "macos")'.dependencies]
|
|
screencapturekit = { version = "1", features = ["async"] }
|
|
coreaudio-sys = "0.2"
|
|
objc = "0.2"
|
|
core-foundation-sys = "0.8"
|
|
|
|
[target.'cfg(target_os = "windows")'.dependencies]
|
|
wasapi = "0.22"
|
|
windows = { version = "0.62", features = [
|
|
"Win32_Foundation",
|
|
"Win32_UI_WindowsAndMessaging",
|
|
"Win32_UI_Accessibility",
|
|
"Win32_UI_Input_KeyboardAndMouse",
|
|
"Win32_System_Com",
|
|
"Win32_System_DataExchange",
|
|
"Win32_System_Memory",
|
|
"Win32_System_Threading",
|
|
] }
|
|
|
|
[target.'cfg(target_os = "linux")'.dependencies]
|
|
webkit2gtk = "2.0"
|
|
|
|
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
|
tauri-plugin-updater = "2.0"
|
|
tauri-plugin-process = "2.0"
|
|
# Pinned to upstream main past PR #147 — the released 0.5.3 crate crashes on
|
|
# macOS 14+ when listen() runs on a background thread because rdev's
|
|
# convert() calls TSMGetInputSourceProperty off the main queue. The main
|
|
# branch adds `set_is_main_thread(false)` to skip that path.
|
|
rdev = { git = "https://github.com/Narsil/rdev", rev = "c14f2dc5c8100a96c5d7e3013de59d6aa0b9eae2" }
|
|
|
|
[features]
|
|
# This feature is used for production builds or when `devPath` points to the filesystem
|
|
custom-protocol = ["tauri/custom-protocol"]
|