diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ff026575..0c523007 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -649,6 +649,46 @@ jobs: updaterJsonPreferNsis: false includeUpdaterJson: true + - name: Build per-user Windows MSI + if: runner.os == 'Windows' + shell: bash + working-directory: frontend + env: + TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} + TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} + run: | + set -euo pipefail + python ../scripts/render-per-user-wix.py \ + --source src-tauri/wix/main.wxs \ + --output src-tauri/target/wix-per-user/main.wxs + bunx tauri build --target ${{ matrix.rust_target }} --bundles msi \ + --config src-tauri/tauri.per-user.conf.json + DIR="src-tauri/target/${{ matrix.rust_target }}/release/bundle/msi" + while IFS= read -r artifact; do + safe=${artifact// (Current User)/_Current_User} + [ "$safe" = "$artifact" ] || mv "$artifact" "$safe" + done < <(find "$DIR" -maxdepth 1 -type f -name '*Current*User*.msi*') + + - name: Publish per-user Windows updater channel + if: runner.os == 'Windows' + shell: bash + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + RELEASE_TAG: ${{ (needs.preview-gate.outputs.is_preview == 'true') && 'preview' || github.ref_name }} + run: | + set -euo pipefail + DIR="frontend/src-tauri/target/${{ matrix.rust_target }}/release/bundle/msi" + MSI=$(find "$DIR" -name '*Current*User*.msi' -type f | head -1) + [ -n "$MSI" ] || { echo "per-user MSI missing"; find "$DIR" -type f; exit 1; } + [ -f "$MSI.sig" ] || { echo "per-user MSI signature missing"; exit 1; } + VERSION=$(jq -r .version frontend/package.json) + python scripts/build_windows_user_manifest.py \ + --repo "$GITHUB_REPOSITORY" --tag "$RELEASE_TAG" --version "$VERSION" \ + --asset "$(basename "$MSI")" --signature-file "$MSI.sig" \ + --output latest-user.json + gh release upload "$RELEASE_TAG" "$MSI" "$MSI.sig" latest-user.json \ + --clobber --repo "$GITHUB_REPOSITORY" + # ── Installer smoke (Phase 0 GATE-03) ───────────────────────────── # Structural verification of the installed/extracted bundle. The thin # uv-venv installer ships NO frozen backend binary (the venv is built on @@ -717,8 +757,9 @@ jobs: shell: bash run: | set -euo pipefail - MSI=$(find frontend/src-tauri/target/${{ matrix.rust_target }}/release/bundle/msi -name "*.msi" | head -1) + MSI=$(find frontend/src-tauri/target/${{ matrix.rust_target }}/release/bundle/msi -name "*.msi" ! -name '*Current*User*' | head -1) echo "Smoke-testing MSI: $MSI" + powershell.exe -NoProfile -ExecutionPolicy Bypass -File scripts/verify-windows-msi.ps1 -MsiPath "$(cygpath -w "$MSI")" # /quiet = no UI, /norestart = don't reboot the runner if a dep asks msiexec.exe //i "$(cygpath -w "$MSI")" //quiet //norestart INSTALL="/c/Program Files/VoiceStudio" @@ -731,6 +772,16 @@ jobs: find "$INSTALL" -type f -path '*backend*main.py' | grep -q . || fail "backend source main.py missing" echo "OK — MSI installed shell + uv + backend resources" + - name: Per-user installer smoke (Windows, non-admin account) + if: runner.os == 'Windows' + timeout-minutes: 8 + shell: bash + run: | + set -euo pipefail + MSI=$(find frontend/src-tauri/target/${{ matrix.rust_target }}/release/bundle/msi -name '*Current*User*.msi' | head -1) + powershell.exe -NoProfile -ExecutionPolicy Bypass \ + -File scripts/smoke-per-user-msi.ps1 -MsiPath "$(cygpath -w "$MSI")" + # linuxdeploy re-links .DirIcon as an ABSOLUTE symlink into the build # machine AFTER tauri's files-map has placed the real icon bytes — the # exact bug #1518 guarded against, resurfacing on the first real tag diff --git a/CHANGELOG.md b/CHANGELOG.md index 980894b8..78e5ffc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,25 +10,39 @@ the frozen-backend fallback mirror it for their toolchains. **Highlights** +- Show estimated and measured model, dependency, cache, and temporary disk costs in the engine catalogue (#1718) - CosyVoice setup guidance now separates downloaded model files from the runtime that makes the engine available. +- MCP tools can now keep audio out of agent context by returning files and accepting base-path-confined file inputs (#1760) — thanks @agudmund! ### Changed ### Added -- The MCP server gains an output mode and a file lane: `OMNIVOICE_MCP_OUTPUT_MODE` (`resources` — the original base64 default — `files`, or `both`) lets `generate_speech` return a URL to the render plus a WAV written under `OMNIVOICE_MCP_BASE_PATH` instead of base64 inline, and `transcribe` / `clone_voice` accept `audio_path` / `ref_audio_path` read from inside that same base path, which acts as the security boundary — so an LLM agent never has to carry audio through its context. +- Windows releases now include an independently updatable per-user MSI that installs and uninstalls without elevation (#1713) +- Engine status and diagnostic bundles now record loaded execution provider, device, precision, fallback stage, accelerator identity, runtime versions, and parent-process memory visibility (#1717) ### Docs +- Local gigastt is now documented as a supported OpenAI-compatible ASR endpoint, with loopback privacy distinguished from remote servers (#1736) — thanks @ekhodzitsky! - The CosyVoice guide now states that packaged builds have no one-click runtime installer and records the exact readiness checks exposed by [Discussion 1631](https://github.com/debpalash/VoiceStudio/discussions/1631). - A production private-API guide now covers pinned containers, root credentials, network isolation, streaming proxies, health checks, upgrades, and benchmark evidence (#1720) +- RX 6700 XT/gfx1031 over WSL2 ROCDXG is now explicitly unverified until a published end-to-end GPU workload proves the mapped path (#1716) ### Fixed +- OpenAI-compatible ASR now requires HTTPS outside loopback and refuses redirects so audio stays on the configured origin (#1736) +- Windows isolated engines now retain direct Job ownership without an extra Python supervisor process that can deadlock the child loader (#1734) +- The setup splash now waits through the backend's full startup budget instead of reporting slow Windows CUDA initialization as stuck after two minutes (#1749) +- Dubbing jobs can now reuse every source-language code produced by automatic ASR detection without a 400 error on the next upload (#1737) +- Incomplete Sherpa-ONNX model snapshots now self-repair before recognizer startup instead of failing on a missing ONNX file (#1733) +- OmniVoice subprocess startup now allows slow packaged Windows Python runtimes to signal readiness before termination (#1711) +- SRT files selected during source analysis now wait for speaker cloning, then replace transcript text without losing voices (#1709) +- Windows MSI deployments can now prohibit WebView2 bootstrap with `DISABLEWEBVIEW2BOOTSTRAP=1`, and `AUTOLAUNCHAPP=0` reliably suppresses first launch (#1714) - Subtitle rows now provide 100 ms timing steppers and flag adjacent overlaps without requiring precise timeline dragging (#1710) - Repair-sync failures now retain uv's final dependency error instead of reporting only an opaque exit status (#1705) - YouTube ingest now retries yt-dlp's transient “page needs to be reloaded” response (#1706) - Dictation model readiness now follows the live Hugging Face cache selected in Settings (#1707) +- Dictation capture now queues native events whenever its webview listener unmounts or reloads instead of emitting them to nobody (#1707) - Desktop-contained backends now exit when their owning app disappears instead of surviving as stale port-3900 processes (#1707) ## [0.5.1] — 2026-08-28 diff --git a/LICENSE-NOTICE.md b/LICENSE-NOTICE.md index f4bb1ac6..2ed1563c 100644 --- a/LICENSE-NOTICE.md +++ b/LICENSE-NOTICE.md @@ -10,10 +10,10 @@ Copyright 2024-present Palash Debnath and VoiceStudio contributors. VoiceStudio is **free and open-source software, licensed under the GNU Affero General Public License, Version 3 (AGPL-3.0)**. You are free to use, -copy, modify, and redistribute it — and that **includes commercial and internal -business use**: run the app, use its outputs commercially, sell the audio you -produce with it, provide professional/client services with it, and deploy it -within your organization. +copy, modify, and redistribute it. That **includes commercial and internal +business use** of the application itself. Model weights, tokenizers, and other +third-party assets retain their own terms; this application license does not +grant or summarize rights under those separate terms. Because this is the **Affero** GPL, one additional obligation applies: if you modify VoiceStudio and make that modified version available to others over @@ -41,6 +41,12 @@ is **separately licensed under Apache License 2.0** by its upstream authors and is not relicensed here. Apache License 2.0 is compatible with, and may be combined under, the GNU AGPL-3.0. See `pyproject.toml`. +Downloaded model weights are not relicensed by VoiceStudio. The default +`k2-fsa/OmniVoice` model card identifies its code as Apache-2.0 and pretrained +weights as CC-BY-NC. Its `audio_tokenizer/LICENSE` contains separate Boson +Higgs Audio 2 and Meta Llama community terms. A commercial license for +VoiceStudio-owned code does not replace any of those terms. + Third-party dependencies retain their own licenses. See `Cargo.lock`, `bun.lock`, and `uv.lock` for the resolved set. diff --git a/README.md b/README.md index 48fc7fc0..5927ef56 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,12 @@
Previously OmniVoice-Studio
-16 TTS engines · 11 ASR engines · 646-language catalogue · macOS, Windows, and Linux
-Local-first. No account, API key, subscription, or usage meter for the core workflow.
+16 TTS engines · 11 ASR engines · 646-language catalogue · macOS, Windows, Linux, and Docker
+No account, API key, subscription, or usage meter for the local workflow.
Install · @@ -36,7 +38,7 @@