* test(shell): backend-lifecycle fault-injection harness Runs spawn_backend_and_wait/supervise_backend against REAL dying child processes and asserts the user receives the correct NAMED diagnosis — not merely that recovery happens. Wrong/missing explanation was 61% of the historical "can't reach the backend" class; this rig is the permanent regression harness for every future lifecycle fix. Seam: OMNIVOICE_BACKEND_CMD (JSON argv or whitespace form) runs any command as "the backend" — venv bootstrap and ffmpeg resolution are skipped, everything else (err-log run offsets, drainer threads, env pinning, real OS pipes, spawn-failure diagnostics) stays real. Plus OMNIVOICE_LOG_DIR (per-test log+marker dirs, also a support tool) and harness-only timing overrides OMNIVOICE_STARTUP_BUDGET_S / OMNIVOICE_SUPERVISOR_POLL_MS whose production defaults are pinned by unit tests. Lifecycle fns genericized over tauri::Runtime for the MockRuntime app; behavior-neutral with the env unset (unit-pinned). Scenarios (tests/backend_lifecycle.rs, scenario children = this test binary re-invoking itself; serial by mutex + CI --test-threads=1): - port conflict (exit 78) → the detectHints-matchable port phrasing - generic chained traceback → root cause survives into the diagnosis and the crash marker - spawn failure → spawn diagnostic reaches the user, NO bogus marker - slow start past budget → timeout names the budget + last stderr - post-Ready crash loop → 3 restarts announced, markers before restarts, "kept crashing" diagnosis naming the last exit - SIGKILL (unix) → named as signal 9 - deliberate kill → supervisor yields silently, no marker, never Failed - deferred-startup FATAL → the named step reaches the user, forensics, and the splash narration CI: harness added to the 3-OS tauri-cross-platform matrix. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore(ci): temporary Windows loader bisect probe for the harness binary Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(shell): embed Common-Controls v6 manifest into Windows test binaries Bisected on #1551: EVERY integration-test binary of this crate died at load on Windows with STATUS_ENTRYPOINT_NOT_FOUND (0xc0000139) — cargo gives test binaries no manifest, so the loader resolves comctl32 v5, which lacks the TaskDialogIndirect entry point tauri's dialog/tray stack imports. build.rs now embeds tests/windows-test.manifest via rustc-link-arg-tests on Windows targets. Bisect probe removed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(test): scenario gate is PID-valued — the parent can't self-inject CodeRabbit on #1551: in a parallel local `cargo test`, the parent's own scenario_child test could observe the armed env and start playing the backend in-process (binding the port, idling 600s). The gate value is now the arming process's PID; a matching PID stays inert, so only the spawned child — a different process — runs the scenario. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
106 lines
4.7 KiB
TOML
106 lines
4.7 KiB
TOML
[package]
|
||
# NOT renamed with the product (VoiceStudio). This is the BINARY name, and
|
||
# scripts/desktop-common.mjs keys its dev-vs-release distinction on it: the dev
|
||
# launcher's pkill matches `omnivoice-studio` and must never match a user's
|
||
# installed app. Renaming it would collapse that distinction.
|
||
name = "omnivoice-studio"
|
||
version = "0.5.0"
|
||
description = "VoiceStudio – AI voice cloning & dubbing desktop app"
|
||
authors = ["Debpalash"]
|
||
license = "AGPL-3.0-only"
|
||
repository = ""
|
||
edition = "2021"
|
||
rust-version = "1.77.2"
|
||
|
||
[lib]
|
||
name = "app_lib"
|
||
crate-type = ["staticlib", "cdylib", "rlib"]
|
||
|
||
[build-dependencies]
|
||
tauri-build = { version = "2.6.0", features = [] }
|
||
|
||
[dependencies]
|
||
serde_json = "1.0"
|
||
serde = { version = "1.0", features = ["derive"] }
|
||
getrandom = "0.3"
|
||
log = "0.4"
|
||
tauri = { version = "2.11.0", features = ["macos-private-api", "protocol-asset", "tray-icon", "image-png"] }
|
||
tauri-plugin-log = "2"
|
||
tauri-plugin-dialog = "2"
|
||
tauri-plugin-window-state = "2.0.0"
|
||
tauri-plugin-updater = "2"
|
||
tauri-plugin-process = "2"
|
||
tauri-plugin-opener = "2"
|
||
tauri-plugin-global-shortcut = "2"
|
||
tauri-plugin-single-instance = "2"
|
||
# Bottom-center placement of the dictation pill/widget window. Replaces the
|
||
# hand-rolled primary-monitor geometry + LogicalPosition math. tray-icon
|
||
# feature enabled because the app ships a system tray (TrayIconBuilder).
|
||
tauri-plugin-positioner = { version = "2", features = ["tray-icon"] }
|
||
|
||
# Cross-platform keyboard simulation for auto-paste after dictation
|
||
enigo = { version = "0.3", features = ["serde"] }
|
||
|
||
# First-run bootstrap: on first launch the Rust setup hook installs `uv`
|
||
# via the official Astral installer script (curl|sh on Unix, irm|iex on
|
||
# Windows), creates a Python 3.11 venv, and runs `uv sync` against the
|
||
# bundled pyproject.toml — which installs torch, whisperx, etc.
|
||
# ureq is used for HTTP health checks and ffmpeg downloads.
|
||
ureq = "2"
|
||
# reqwest is used for GitHub Releases API calls (list_releases command).
|
||
reqwest = { version = "0.13", features = ["json"] }
|
||
# semver is used by the channel-aware updater (updater_channel.rs) to rank
|
||
# builds across the stable/preview channels (#326); same major as the
|
||
# `Version` type tauri-plugin-updater re-exports (already in the lockfile).
|
||
semver = "1"
|
||
|
||
# ── Rust IPC commands (cross-platform) ──
|
||
# get_sysinfo: CPU + RAM metrics without HTTP round-trip
|
||
sysinfo = { version = "0.33", default-features = false, features = ["system"] }
|
||
# hf_cache_scan: walk HF cache directory 3-5× faster than Python
|
||
walkdir = "2"
|
||
# First-run setup screen: per-path free-disk-space probe (statvfs /
|
||
# GetDiskFreeSpaceExW) for the minimum-storage install gate
|
||
fs4 = "0.13"
|
||
# Cross-platform home/config/data directories (config.rs, setup.rs)
|
||
dirs-next = "2"
|
||
# Native (OS-side) clipboard write for dictation auto-paste: the widget window
|
||
# is unfocused on macOS so the simulated ⌘V reaches the target app, which makes
|
||
# the WebView clipboard APIs fail silently there (#287)
|
||
arboard = "3"
|
||
|
||
[target.'cfg(windows)'.dependencies]
|
||
zip = { version = "2", default-features = false, features = ["deflate"] }
|
||
# WebView2 PermissionRequested handler: auto-grant media-capture for the
|
||
# app's own origin so getUserMedia() works in the dictation widget (#323).
|
||
# Versions match what wry already locks — no new native code is pulled in.
|
||
webview2-com = "0.38"
|
||
windows-core = "0.61"
|
||
# Raw HWND access (GetWindowLongPtrW/SetWindowLongPtrW/ShowWindow) to mark the
|
||
# dictation pill WS_EX_NOACTIVATE so showing it doesn't steal Win32 foreground
|
||
# activation (#982 — Windows counterpart of #287's macOS focus-steal fix).
|
||
# Version pinned to match what `tauri` itself already resolves to (0.61.x) so
|
||
# `WebviewWindow::hwnd()`'s return type and our syscalls share the exact same
|
||
# `HWND` type — no second copy of the crate enters the dependency graph.
|
||
# Win32_System_Registry: check_microphone reads the CapabilityAccessManager
|
||
# ConsentStore mic toggle (RegGetValueW) for the permissions UX.
|
||
windows = { version = "0.61", features = ["Win32_Foundation", "Win32_UI_WindowsAndMessaging", "Win32_System_Registry"] }
|
||
|
||
[target.'cfg(unix)'.dependencies]
|
||
libc = "0.2"
|
||
|
||
[target.'cfg(target_os = "linux")'.dependencies]
|
||
webkit2gtk = "2.0"
|
||
# Wayland compositors do not expose global keys through X11 grabs. Use the
|
||
# standard xdg-desktop-portal GlobalShortcuts interface there; zbus is already
|
||
# present transitively through Tauri's opener/single-instance plugins.
|
||
zbus = "5.16"
|
||
|
||
[dev-dependencies]
|
||
# Scoped-reset tests build real directory trees to prove the delete guard only
|
||
# ever removes paths inside a validated OmniVoice root.
|
||
tempfile = "3"
|
||
# MockRuntime app for the backend-lifecycle fault-injection harness
|
||
# (tests/backend_lifecycle.rs) — feature-unifies onto the main dep.
|
||
tauri = { version = "2.11.0", features = ["test"] }
|