Files
VoiceStudio/frontend/src-tauri/Cargo.toml
T
Palash DebnathandClaude Fable 5 3d0c9605df test(shell): backend-lifecycle fault-injection harness (#1551)
* 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>
2026-08-14 18:45:27 +00:00

106 lines
4.7 KiB
TOML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
[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"] }