| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
docs: document Apple Silicon Metal build parity and drop continue-on-error (#2105) - Drops experimental flag (continue-on-error) on macos-14 in build-omnivoice-tts.yml now that omnivoice.cpp builds cleanly with -DGGML_METAL=ON at the pinned SHA. - Updates bin/README.md, backend/engines/omnivoice_gguf/README.md, and SPIKE-01 ADR to document verified Apple Silicon Metal acceleration. - Corrects workflow reference in bin/README.md. - Adds changelog credit for @martinezpl. Closes #2105 | 10 天前 | |
chore(agents): record issue tracker, triage labels and domain-doc layout (#1400) Scaffolds the per-repo agent configuration the engineering skills assume: where issues live (GitHub Issues via the gh CLI), the five canonical triage labels, and the single-context domain-doc layout. Adds docs/agents/{issue-tracker,triage-labels,domain}.md and an '## Agent skills' block in both CLAUDE.md and AGENTS.md so the two stay in sync. Documentation only — no runtime code is touched. Review fixes: CONTEXT.md is now described as 'read it when it exists' rather than stating its absence as permanent, and both directory-tree fences carry a language identifier (markdownlint MD040). | 1 个月前 | |
fix(export): open Windows caption paths in ffmpeg hardsub filters (#2312) * fix(export): open Windows caption paths in ffmpeg hardsub filters ffmpeg subtitles and ass filters do not open a quoted C:\ path after backslashes are doubled. Convert to forward slashes, then escape colon and quote, so burned-in line and karaoke captions render. * docs(changelog): note the Windows hardsub caption path fix (#2312) * fix(export): preserve caption paths across ffmpeg parser layers (#2312) --------- Co-authored-by: Palash Debnath <4178343+debpalash@users.noreply.github.com> | 23 小时前 | |
fix(clone): rank long references with installed speech model (#2301) * fix(clone): rank long references with the installed speech model (#2281) A clip over 20 s dropped its transcript and asked OmniVoice's cached Whisper snapshot to score 15 s windows. That snapshot is not the Model Catalogue recognizer, so synthesis failed even when Faster-Whisper was already installed. * docs(changelog): keep the long-reference note under Unreleased The rebase had dropped it into the already tagged 0.5.6 section. * fix(clone): key the long-reference window to the recognizer that picked it The cached prompt did not record which 15 s passage or which installed speech model produced it, so a later recognizer could reuse the wrong window. The notes now state that only that window is cloned. * fix(clone): lock the long-reference window cache Two GPU workers can rank long clips at once. The window list now uses the same lock as the prompt cache, so one request cannot drop the other's passage. * fix(clone): keep long-reference ranking compatible and cached Decode clips libsndfile cannot read, key the window by every recognizer that may transcribe it, and remember a miss so the next chunk does not rank the same clip again. * fix(clone): keep reference diagnostics path-free * test(clone): isolate selected-window prompt cache identity --------- Co-authored-by: Palash Debnath <4178343+debpalash@users.noreply.github.com> | 18 小时前 | |
fix(dictation): dispatch macOS keyboard operations on the main thread | 6 天前 | |
fix(electron): ship FUSE-free AppImages with zsync updates (#2329) * feat(electron): publish AppImage zsync updates (#2327) * Use FUSE-independent AppImage runtime (#2328) * Launch packaged AppImage in Linux smoke checks * Postprocess AppImages for source installs and dist builds * Keep external AppImage updates on the matching release channel * Run Linux source install smoke against the PR main revision * Accept shallow PR commits in installer smoke source mirror | 10 小时前 | |
feat(integrations): guided Twilio setup and responsive integration pages (#2304) * feat(integrations): guided Twilio setup and responsive integration pages - Twilio detail page is a step-by-step checklist (account, tunnel, phone number, voice and behavior) with live status, per-step saves, exact cloudflared/ngrok commands for the OS and gateway port, copyable webhook URL, readiness rail, test card with explicit disabled reasons, recent calls and a "How it works" security explainer. Calls backend endpoints (/calls/settings, /calls/readiness) and the /calls route are feature-detected. - Detail pages: per-integration taglines from the registry, own category labels (no borrowed "Dubbing" key), one docs link, full-width scroller with a two-column container-query layout and sticky rail. - Select triggers always label their value (no raw __default__, auto, *, or locale codes); a source-scan test guards the class. - Catalog and featured logos open the in-app page, never a vendor website. - Gateway state exposes preferred_port so the tunnel command is exact before calls are turned on. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs(changelog): reference #2304 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(integrations): exact tunnel port and honest webhook status - preferred_port uses the same free-port probe as gateway start, so a taken base port no longer yields a tunnel command for the wrong service. - The phone-number step is Done only after a call that passed the signature check; rejected or busy attempts do not count. - Docs: Learn more applies to pages with a built-in setup. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs(changelog): list the #2304 docs update Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(i18n): phone step completes on a signed call; merge changelog Docs Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> | 1 天前 | |
Make Electron the default desktop and refresh setup documentation | 8 天前 | |
fix(clone): long references clone on OmniVoice; engines report the reference length they use (#2286) * fix(clone): let long references clone and say what each engine uses OmniVoice rejects a transcript paired with a clip over 20 s, and every automatic path produced exactly that pair: Voice Clone and /generate transcribed the whole clip, and saved profiles kept that transcript. A 25 s saved voice was permanently unusable on the default engine even though the model can pick its best 15 s passage from clips up to 75 s. - Drop whole-clip transcripts on over-long OmniVoice references at the engine boundary (prompt cache, inline fallback, sidecar) and skip the wasted whole-clip ASR; a transcript typed on /generate still gets the actionable [clone_ref_too_long] error. - VoxCPM2 ignores a whole-clip transcript once its 30 s cap cuts the clip. - Engines advertise max_ref_seconds/ref_strategy via list_backends(). - Electron Voice Clone shows an engine-aware note instead of the 15 s trim toast and leaves the transcript to engines that pick a passage. Refs #2281 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test(clone): patch the sidecar backend's own base class Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(clone): review fixes for long references (#2281) - A transcript sent with a saved voice over the limit gets the same [clone_ref_too_long] 400 as an upload instead of being dropped. - omnivoice_ref_text treats blank text as no transcript. - The VoxCPM2 sidecar advertises its 30 s head limit; a parity test pins every sidecar's reference metadata to its in-process engine. - The Voice Clone transcript hook withdraws its own whole-clip transcript when the engine starts picking the passage itself, keeping user edits. - Changelog credits use the standard form. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(generate): probe reference length off the event loop Non-WAV clips decode through ffmpeg to measure length; doing it inline on the async route stalled every other request. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> | 2 天前 | |
feat: rename the product to VoiceStudio (previously OmniVoice-Studio) Renames what users see. The app, the installers, the window title, the docs and all 21 locales now say VoiceStudio, with "(previously OmniVoice-Studio)" noted near the title of each doc surface so people recognise it. Deliberately NOT renamed, because renaming any of them silently breaks an existing install — there is no legacy-path fallback anywhere in this codebase: - bundle identifier com.debpalash.omnivoice-studio (MSI UpgradeCode, macOS TCC grants, managed venv, WebView localStorage, the single-instance lock) - data directories OmniVoice / .omnivoice and omnivoice.db - the ~150 OMNIVOICE_* environment variables - the X-OmniVoice-* HTTP headers (a wire protocol) - the published Docker image paths - the OmniVoice ENGINE, which is a model name and not this product tests/test_identity_paths_survive_the_rename.py pins every one of those so a future well-meaning sweep cannot orphan a user's library. Linux .deb users install a new package name and should apt remove omnivoice-studio; that note is in the changelog. | 1 个月前 | |
fix(auth): gate onboarding replacement on known token state | 17 天前 | |
feat(electron): add full VoiceStudio desktop app | 10 天前 | |
feat: improve dictation controls and creative workspaces | 15 天前 | |
ci: make Electron the only active desktop target (#2220) Make Electron the maintained desktop target, preserve frozen Tauri v0.5.3 updater feeds, and align setup, smoke checks, release policy and documentation. Validated by full CI, cross-platform smoke and install tests, security checks, and bot review. | 5 天前 | |
fix(electron): ship FUSE-free AppImages with zsync updates (#2329) * feat(electron): publish AppImage zsync updates (#2327) * Use FUSE-independent AppImage runtime (#2328) * Launch packaged AppImage in Linux smoke checks * Postprocess AppImages for source installs and dist builds * Keep external AppImage updates on the matching release channel * Run Linux source install smoke against the PR main revision * Accept shallow PR commits in installer smoke source mirror | 10 小时前 | |
feat(dub): realtime dub preview (#1769) Opt-in live preview for dub segments: edits debounce into a streamed /ws/tts synthesis played through the chunk player, with cancellation preserved through buffered playback. Maintainer fixes: /ws/tts added to the backend ticket allowlist (feature was dead off-loopback), handshake failures surface a toast, loopback-only plaintext refusal reverted to keep the documented remote-GPU setup working, PCM16 decode hardened. Thanks @mvanhorn! | 21 天前 | |
feat(calls): phone call agent — outbound Twilio calls and inbound agent mode (#2306) * feat(calls): phone call agent backend — outbound/inbound calls in your voice Adds a task-driven call agent on top of the Twilio integration: outbound calls via Twilio REST with signed status callbacks, a provider-agnostic conversation loop (energy VAD -> capture ASR -> streamed LLM turn -> streaming TTS, barge-in via clear), persisted call sessions (alembic 0012), the /calls local API with SSE events, take-over/say/hangup, and inbound agent mode. Owner safeguards: editable AI disclosure on by default, outbound voices gated to verified-own or designed profiles (403), one explicit request per call with max 1-2 concurrent, recording only when enabled and disclosed. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs(changelog): reference #2306 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs(changelog): add Unreleased highlights Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(calls): address review — affirmative recording notice, one agent-call limit, wider number guard - Recording needs an affirmative notice; negated disclosures never record (greptile) - max_concurrent now limits agent calls in both directions (greptile) - Sensitive-number guard also catches comma and Unicode-dash separators (greptile) - Constant upsert SQL, https-only urlopen guard, no BaseException catch (code scanning) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(calls): always finalize a connected call; allow brief numbers in any phone style - Finalize agent calls in a shielded finally so a failed/cancelled stream frees its slot (coderabbit) - Guard allows numbers from the brief written with parentheses or a country code (coderabbit) - Docs: the no-LLM fallback needs a configured greeting (coderabbit) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test(calls): wait on record changes instead of sleeping; assert the injected stream failure Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> | 1 天前 | |
fix(media): say plainly when a file has no audio track (#2308) * fix(media): name a video with no audio track instead of dumping ffmpeg's exit 234 Loading a video-only MP4 in Dub failed at `extract` with ffmpeg's raw stream dump ("FFmpeg exited with code 234 ... Output file does not contain any stream ... Invalid argument"). Every audio-extract site now probes for an audio stream first (ffprobe, then the ffmpeg stream list) and recognizes ffmpeg's no-stream wording as a fallback, raising NoAudioTrackError with a VoiceStudio sentence and the NO_AUDIO_TRACK failure class: dub ingest, batch dub, the ASR decoder, /transcribe, /v1/audio/transcriptions, clone references and gallery imports. HTTP surfaces return a structured 422 (OpenAI routes: 400 no_audio_track); Electron shows the localized message in all 21 locales and keeps the diagnostic behind Copy diagnostic. ffmpeg's stderr stays in the log. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test+docs: reload-safe no-audio assertions; changelog entry (#2308) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(openai): keep an engine-raised no-audio error as 400 when the probe cannot run Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> | 1 天前 | |
fix(api): OpenAI SDK and Agents SDK compatibility for the /v1 speech routes (#2290) * fix(api): make /v1 audio routes work with the openai and Agents SDKs - Alias every OpenAI TTS model id (gpt-4o-mini-tts, dated snapshots) and current voice name to the active engine; real engine ids still win. - Map OpenAI `instructions` to the engine instruct (explicit instruct wins; OmniVoice keeps only its voice-design tags so prose can't fail a request). - pcm is 24 kHz int16 LE mono; mp3/opus/aac are encoded by ffmpeg with a matching Content-Type, or a clear 400 before any GPU work; add stream_format audio/sse and the {"id": ...} voice object. - Add GET /v1/models(/{id}) and POST /v1/audio/translations. - Transcriptions forward language/prompt/temperature to backends whose transcribe() declares them (Whisper family, isolated sidecar, remote OpenAI-compatible ASR), report the detected language, and return OpenAI segments plus words for timestamp_granularities[]=word. - /v1 errors use OpenAI's {"error": {...}} shape (detail kept), 400 for validation failures. - Electron: OpenAI Agents integration page shows a copyable VoicePipeline snippet for the live backend. - Contract test drives every route through the real openai SDK. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs(changelog): reference #2290 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(api): honour advertised STT ids and make the Agents LLM explicit Review follow-ups (Greptile, #2290): - /v1/models lists only the active ASR engine for STT; a transcription or translation naming another VoiceStudio ASR engine id gets a 400 model_not_active instead of being silently served by the active one. - The OpenAI Agents snippet configures the agent's LLM explicitly from AGENT_LLM_BASE_URL / AGENT_LLM_MODEL (a local OpenAI-compatible server) and fails fast when unset, so it never falls back to a hosted model. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore(api): explain best-effort temp cleanup (CodeQL empty-except) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(api): refuse translation on transcription-only Whisper checkpoints Whisper large-v3-turbo (and Distil / .en checkpoints) ignore task=translate and return the source language, which /v1/audio/translations would have labelled English with a 200 (CodeRabbit, #2290). Backends now report supports_translation() from their loaded checkpoint and the route returns 400 unsupported_task before inference. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> | 2 天前 | |
docs(readme): lead with download + first clone; seed benchmarks page (#1555) * docs(readme): lead with download + first clone; seed benchmarks page Quickstart (installers, install guides, a three-step first-clone walkthrough) moves above What's-new/Features in both READMEs — visitors get the action before the pitch. New docs/benchmarks.md anchors measured per-engine/device numbers on the bench_pipeline.py harness, community-contributed, no estimates. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(changelog): entry for the README conversion restructure (#1555) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(bench): emit RTF + CUDA peak VRAM; guard NaN RAM; define the benchmarks schema Bot harvest on #1555: the tts stage now prints RTF per warm measurement and CUDA peak VRAM (None elsewhere — no made-up zeros), the stage floor refuses unmeasurable RAM instead of sailing past a NaN comparison (FLOOR_GB=0 overrides), docs/benchmarks.md columns map 1:1 to what the harness prints, and the download badges say they open the release page. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(readme): link palash.dev from the maker section Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(bench): name the resolved engine, track VRAM from resolution, comment the guards Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(readme): the quick-switch gif is the hero image The hero shows motion now; the Launchpad screenshot moves into the 0.5.0 What's-new slot so nothing appears twice. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(bench): peak VRAM is reserved memory; adapter engines name their model Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(bench): subprocess-isolated engines report VRAM n/a, not a parent-side zero Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(bench): out-of-process detection is declarative; sherpa rows name their model 'runs_out_of_process' is now a TTSBackend attribute set by SubprocessBackend AND omnivoice-gguf (which inherits TTSBackend directly but spawns a binary per generate — the isinstance check missed it). Duck-typed for the same module-purge reason as _is_subprocess_isolated. Sherpa-onnx identity comes from _model_dir's basename when _model_id is absent. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(bench): backends self-report model identity via TTSBackend.model_identity() Greptile enumerated the adapter engines one at a time (mlx _model_id, sherpa _model_dir, cosyvoice env-only) — the attribute sniffing rots per engine. The hook fixes the class: each multi-model backend reports its own identity, the profiler just asks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> | 1 个月前 | |
feat(electron): add full VoiceStudio desktop app | 10 天前 | |
feat(calls): Calls workspace — place, watch and review agent phone calls (#2305) * feat(calls): Calls workspace to phone someone in your own voice New Electron workspace built on the /calls API: readiness checklist with Fix links, new-call form (E.164 validation, task brief with examples, verified/designed voices only, editable AI disclosure, max length, plan preview, confirm step), live view over SSE with reconnect (timeline, agent state, transcript, take over, say, hang up), after-call outcome and summary, history, and inbound mode settings. Falls back to a guided state when the backend predates the Calls API. Responsive: three panes at >=1440px, two below, one column under 1024px. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs(changelog): reference #2305 for the Calls workspace Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(calls): keep streamed transcript on stale resync; refresh on terminal status A reconnect snapshot now merges with lines already streamed instead of replacing them, and a terminal status event refetches the finished call even without a separate ended event. The guide links the Twilio setup page instead of an API page that is not in this PR. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(calls): safer confirm focus, no guessed country for +1/+7, keep SSE retrying - The confirm dialog focuses Cancel so a held Enter cannot dial. - Shared calling codes (+1, +7) no longer claim a single country. - After the retry budget the stream reports lost but keeps retrying at the capped delay, so a long call still recovers. - The live route smoke treats the Calls 404 fallback as expected. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat(calls): align the client with the call-agent backend (#2306) Type the extra CallRecord fields (disclosure, takeover, agent_state, recording, error, timeline) and settings.user_name; add deleteCall and the recording URL. An unedited disclosure is left to the backend, which fills {name}; the form previews it filled in and marks it as played in full, since it cannot be interrupted. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(calls): a cleared disclosure never opts out while the switch is on Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(calls): keep ended calls ended and keep the last utterance on hang-up Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(calls): merge the ended record before finalizing interim lines Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> | 1 天前 | |
feat: rename the product to VoiceStudio (previously OmniVoice-Studio) Renames what users see. The app, the installers, the window title, the docs and all 21 locales now say VoiceStudio, with "(previously OmniVoice-Studio)" noted near the title of each doc surface so people recognise it. Deliberately NOT renamed, because renaming any of them silently breaks an existing install — there is no legacy-path fallback anywhere in this codebase: - bundle identifier com.debpalash.omnivoice-studio (MSI UpgradeCode, macOS TCC grants, managed venv, WebView localStorage, the single-instance lock) - data directories OmniVoice / .omnivoice and omnivoice.db - the ~150 OMNIVOICE_* environment variables - the X-OmniVoice-* HTTP headers (a wire protocol) - the published Docker image paths - the OmniVoice ENGINE, which is a model name and not this product tests/test_identity_paths_survive_the_rename.py pins every one of those so a future well-meaning sweep cannot orphan a user's library. Linux .deb users install a new package name and should apt remove omnivoice-studio; that note is in the changelog. | 1 个月前 | |
feat: rename the product to VoiceStudio (previously OmniVoice-Studio) Renames what users see. The app, the installers, the window title, the docs and all 21 locales now say VoiceStudio, with "(previously OmniVoice-Studio)" noted near the title of each doc surface so people recognise it. Deliberately NOT renamed, because renaming any of them silently breaks an existing install — there is no legacy-path fallback anywhere in this codebase: - bundle identifier com.debpalash.omnivoice-studio (MSI UpgradeCode, macOS TCC grants, managed venv, WebView localStorage, the single-instance lock) - data directories OmniVoice / .omnivoice and omnivoice.db - the ~150 OMNIVOICE_* environment variables - the X-OmniVoice-* HTTP headers (a wire protocol) - the published Docker image paths - the OmniVoice ENGINE, which is a model name and not this product tests/test_identity_paths_survive_the_rename.py pins every one of those so a future well-meaning sweep cannot orphan a user's library. Linux .deb users install a new package name and should apt remove omnivoice-studio; that note is in the changelog. | 1 个月前 | |
feat: rename the product to VoiceStudio (previously OmniVoice-Studio) Renames what users see. The app, the installers, the window title, the docs and all 21 locales now say VoiceStudio, with "(previously OmniVoice-Studio)" noted near the title of each doc surface so people recognise it. Deliberately NOT renamed, because renaming any of them silently breaks an existing install — there is no legacy-path fallback anywhere in this codebase: - bundle identifier com.debpalash.omnivoice-studio (MSI UpgradeCode, macOS TCC grants, managed venv, WebView localStorage, the single-instance lock) - data directories OmniVoice / .omnivoice and omnivoice.db - the ~150 OMNIVOICE_* environment variables - the X-OmniVoice-* HTTP headers (a wire protocol) - the published Docker image paths - the OmniVoice ENGINE, which is a model name and not this product tests/test_identity_paths_survive_the_rename.py pins every one of those so a future well-meaning sweep cannot orphan a user's library. Linux .deb users install a new package name and should apt remove omnivoice-studio; that note is in the changelog. | 1 个月前 | |
chore: flatten project by moving all contents from submodule to root | 5 个月前 | |
ci: make Electron the only active desktop target (#2220) Make Electron the maintained desktop target, preserve frozen Tauri v0.5.3 updater feeds, and align setup, smoke checks, release policy and documentation. Validated by full CI, cross-platform smoke and install tests, security checks, and bot review. | 5 天前 | |
feat(catalogue): engine list + detail, weights under their engine The engine matrix (five columns, three-line rows, every chip on every row) becomes a shadcn table with three columns — Engine · Runs on · Status — and one primary action per row (Use / Install). Everything else lives in a detail panel for the selected row: GPU compatibility chips, isolation, hints and reasons, health and self-test probes, one-click install progress, setup snippet, disk usage, docs, license, the curated-model picker, and now the engine's downloadable WEIGHTS. Weights belong to their engine: every models.yaml entry names the backend ids that load it (`engines:`), the detail panel lists and installs them (EngineWeights, on the model store's install/cancel/remove flow via the extracted useModelDownloads hook), and the sherpa-onnx engine shows its dictation-model picker there. The page's "Downloaded weights" list and recommendation card are gone; only weights no engine owns (speaker diarisation) remain in a small "Other weights" list. A backend test pins the mapping: every entry has an `engines` list and every id is a real backend. - useEngineInventory: the matrix's state machines extracted verbatim (shared/local fetch, residency, health/self-test cooldowns, install poller with overlap guard + epoch, disk-usage generations, license). - Row status phrases: GPU active / CPU fallback / CPU / Available / Needs setup / Installing… / failed; routing "unavailable" never reads Ready. Group captions keep "Ready to use" / "Add more engines". - Engine titles read "Engines" (each locale's own word); backend "Model Catalogue → Engines/Models" messages and docs updated to the new structure. - Dead matrix CSS (phone-tier grid) removed; scopeReco and RecoBanner gone. | 14 天前 | |
feat(electron): add full VoiceStudio desktop app | 10 天前 | |
feat(electron): add full VoiceStudio desktop app | 10 天前 | |
feat(dub): create a Stories script from a finished dub (#2300) * feat(dub): create a Stories script from a finished dub A dub already knows who says what — diarisation groups the segments and the Cast strip gives each speaker a voice — but re-voicing that same conversation as a Story meant retyping every line and reassigning every voice by hand. Create Story carries it across: one character per speaker in first-speaking order, one line per segment, each character keeping the saved voice the dub assigned. Auto-clones bind by speaker name to a saved profile; design presets and auto-clones that were never saved fall back to the cast default rather than leaving a reference that dangles. A merged row is expanded into the attributed spans `segmentParts` records. Reading only the row's top-level speaker_id would put the second character's words in the first character's voice — the #1612 failure on a new surface, since merging spreads `...first`. Adjacent spans of one speaker are rejoined, so a merge that repairs a single speaker's broken sentence stays one line, and the recorded offsets are treated as hints rather than truth, so editing the merged text after the merge cannot silently drop words. Implements docs/specs/longform/30-dub-to-stories.md for Electron; the spec predates the Tauri sunset and names the retired app's files. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs(changelog): move this entry to Unreleased and add its PR ref 0.5.6 was tagged while this branch was open, so merging main folded the entry into the released section — taking its Highlights to 11 against the 3–5 the style gate allows for a numbered release. Restore 0.5.6 exactly as tagged and put this work under Unreleased, where the cardinality rule does not apply, with the (#2300) ref the gate wants. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(dub): observe the Story navigation instead of detaching it `detached-renderer-tasks` forbids `void navigate(...)` in the renderer: a rejected transition would vanish instead of reaching the repair agent. Route it through `runRendererTask` like the other cross-page jumps. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(dub): deduplicate confirmation dialog after main merge --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: Palash Debnath <4178343+debpalash@users.noreply.github.com> | 17 小时前 | |
feat(electron): add full VoiceStudio desktop app | 10 天前 | |
feat(electron): add full VoiceStudio desktop app | 10 天前 | |
fix(llm): constrain authenticated discovery to typed native models | 4 天前 | |
feat(electron): add full VoiceStudio desktop app | 10 天前 | |
feat(dub): create a Stories script from a finished dub (#2300) * feat(dub): create a Stories script from a finished dub A dub already knows who says what — diarisation groups the segments and the Cast strip gives each speaker a voice — but re-voicing that same conversation as a Story meant retyping every line and reassigning every voice by hand. Create Story carries it across: one character per speaker in first-speaking order, one line per segment, each character keeping the saved voice the dub assigned. Auto-clones bind by speaker name to a saved profile; design presets and auto-clones that were never saved fall back to the cast default rather than leaving a reference that dangles. A merged row is expanded into the attributed spans `segmentParts` records. Reading only the row's top-level speaker_id would put the second character's words in the first character's voice — the #1612 failure on a new surface, since merging spreads `...first`. Adjacent spans of one speaker are rejoined, so a merge that repairs a single speaker's broken sentence stays one line, and the recorded offsets are treated as hints rather than truth, so editing the merged text after the merge cannot silently drop words. Implements docs/specs/longform/30-dub-to-stories.md for Electron; the spec predates the Tauri sunset and names the retired app's files. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs(changelog): move this entry to Unreleased and add its PR ref 0.5.6 was tagged while this branch was open, so merging main folded the entry into the released section — taking its Highlights to 11 against the 3–5 the style gate allows for a numbered release. Restore 0.5.6 exactly as tagged and put this work under Unreleased, where the cardinality rule does not apply, with the (#2300) ref the gate wants. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(dub): observe the Story navigation instead of detaching it `detached-renderer-tasks` forbids `void navigate(...)` in the renderer: a rejected transition would vanish instead of reaching the repair agent. Route it through `runRendererTask` like the other cross-page jumps. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(dub): deduplicate confirmation dialog after main merge --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: Palash Debnath <4178343+debpalash@users.noreply.github.com> | 17 小时前 | |
fix(electron): register notification hit region after titlebar drag regions | 9 天前 | |
ci: make Electron the only active desktop target (#2220) Make Electron the maintained desktop target, preserve frozen Tauri v0.5.3 updater feeds, and align setup, smoke checks, release policy and documentation. Validated by full CI, cross-platform smoke and install tests, security checks, and bot review. | 5 天前 | |
Merge branch 'review/2211-current' into review/2208-current # Conflicts: # CHANGELOG.md # docs/electron-parity.md # electron/src/renderer/src/components/app-shell/workspace-sidebar.tsx | 6 天前 | |
fix: keep the backend alive on pre-Ampere NVIDIA GPUs (#2135) On a Tesla T4 the backend exited during the first /generate with no traceback and no HTTP response, leaving the client with RemoteDisconnected and every later call with ConnectionRefused. Three separate defects combined, which is why none of the reporter's workarounds helped. 1. torch.compile(mode="reduce-overhead") captures CUDA graphs. T4 (sm_75) passed the existing arch gate, so capture was attempted and aborted the process from inside the native CUDA library — below the interpreter, where neither the #278 eager-fallback wrapper nor any except clause can see it. The compile mode is now resolved per GPU: Ampere (sm_80) and newer keep the cudagraph mode, older cards drop to the non-cudagraph "default" mode and keep their compiled Inductor kernels. Fails open on any probe error, so no GPU that works today loses the optimization. OMNIVOICE_FORCE_CUDAGRAPH=1 restores it. 2. should_torch_compile() never read TORCH_COMPILE_DISABLE. main.py sets it on win32, build_engine_env injected it into subprocesses, and docs/install/windows.md tells users to export it — but the in-process gate ignored it, so the reporter exported the documented variable and still got "torch.compile applied". The gate now honours TORCH_COMPILE_DISABLE / TORCHDYNAMO_DISABLE / TORCHINDUCTOR_DISABLE on every platform, and an env opt-out on the parent propagates to engine subprocesses. The settings DB path is logged alongside the toggle: the reporter had three omnivoice.db files and edited one the backend never opened. 3. Settings -> Performance -> "Disable torch.compile" was rendered disabled outside Windows in both the Tauri and Electron UIs, so the one control that would have stopped this was unreachable for the affected Linux user. The toggle is now live on every platform, and build_engine_env honours it everywhere rather than only on win32. Also arms faulthandler before torch is imported, so a fatal native signal writes the faulting thread's Python stack to backend_err.log instead of the process vanishing silently. This does not prevent a crash; it makes one diagnosable. OMNIVOICE_DISABLE_FAULTHANDLER=1 skips it. Tests fail before / pass after, verified by stashing the source and running the new tests against unfixed code. The crash test kills a real child interpreter with a real SIGSEGV and requires a named Python frame in the output. test_torch_compile_path_gate's fixture now clears the compile-disable env vars: main.py setdefaults them on win32, so on a Windows runner they leaked into os.environ and decided those tests. Not verified on real hardware — no Turing GPU available. The sm_80 floor is inferred from the crash report and from docs/hardware-notes-tesla-t4.md, which already flagged cudagraphs on T4 as attempted by default and never evaluated. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> | 8 天前 | |
feat(electron): add full VoiceStudio desktop app | 10 天前 | |
fix(review): preserve API routing and normalize AudioSeal model rates | 4 天前 | |
feat(electron): add full VoiceStudio desktop app | 10 天前 | |
fix(electron): reconcile error class handling after main merge | 6 天前 | |
fix(electron): improve cloning, setup recovery and render diagnostics (#2271) * feat(diagnostics): trace local render stages and guard long-form budgets * fix(electron): require managed Python and verify native tokenizer setup * fix(asr): preserve initialization causes without speculative reinstall advice * style: format runtime setup regressions * fix(electron): preserve existing interpreters during runtime repair * fix(electron): validate existing Python before runtime retry * fix(electron): reinstall failed native tokenizer on runtime retry * fix(electron): evict corrupted tokenizer cache before repair * fix: preserve target language when choosing clone references * test: keep render tracing regressions isolated across the suite * docs: record cross-language cloning fix * fix(electron): keep shared-URL integration cards distinct * chore: bump maintained app version to 0.5.5 * docs: record integration catalog filtering fix * test: align runtime dependency probe with native tokenizer check | 3 天前 | |
feat(electron): add full VoiceStudio desktop app | 10 天前 | |
Integrate reviewed PR #2242 # Conflicts: # CHANGELOG.md # docs/electron-tools.md | 5 天前 | |
feat(electron): add full VoiceStudio desktop app | 10 天前 | |
feat(electron): add full VoiceStudio desktop app | 10 天前 | |
fix(audiocpp): ship verified CPU runtime | 16 天前 | |
feat: rename the product to VoiceStudio (previously OmniVoice-Studio) Renames what users see. The app, the installers, the window title, the docs and all 21 locales now say VoiceStudio, with "(previously OmniVoice-Studio)" noted near the title of each doc surface so people recognise it. Deliberately NOT renamed, because renaming any of them silently breaks an existing install — there is no legacy-path fallback anywhere in this codebase: - bundle identifier com.debpalash.omnivoice-studio (MSI UpgradeCode, macOS TCC grants, managed venv, WebView localStorage, the single-instance lock) - data directories OmniVoice / .omnivoice and omnivoice.db - the ~150 OMNIVOICE_* environment variables - the X-OmniVoice-* HTTP headers (a wire protocol) - the published Docker image paths - the OmniVoice ENGINE, which is a model name and not this product tests/test_identity_paths_survive_the_rename.py pins every one of those so a future well-meaning sweep cannot orphan a user's library. Linux .deb users install a new package name and should apt remove omnivoice-studio; that note is in the changelog. | 1 个月前 | |
fix(longform): keep the chapter cache across data-dir changes and power loss (#2284) * fix(longform): keep the chapter cache across data-dir changes and power loss Chapter and segment cache keys embedded the reference audio's absolute path, so any change in how the data dir is reached re-keyed every cached chapter. Key by the voices-dir-relative path instead; caches written under the absolute path are still found and moved to the new key. Flush cached chapter/segment WAVs and the resume manifest before their rename (F_FULLFSYNC on macOS) so a power-off cannot leave an empty manifest or a torn chapter, reject torn chapter WAVs on lookup, and log which input changed when a chapter misses. Refs #2279 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(longform): harden #2279 cache portability, torn-WAV checks and tests - Tests resolve app modules at call time: other suites pop and re-import core.config, so the module-level import patched a stale object that the code under test no longer read (CI-only failures). - Record the voices roots a cache was rendered under and probe legacy (absolute-path) keys under each, so upgrading then relocating the data dir still finds chapter, segment and remote entries. - wav_is_complete walks the RIFF chunks so a tail torn by a power-off is a miss for chapters, segments and remote entries (was: size vs payload only, missing header bytes). - Remote chapter publication is durable; a failed legacy move uses the legacy file in place instead of re-rendering remotely. - Changelog credit, CodeQL empty-except, lexicon-leak and durable-order test coverage. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(longform): record the voices root at startup and on data-dir moves - Backend Phase B notes the current voices root in an existing longform cache, so upgrading and then moving the data dir before any render still finds chapters keyed by the old absolute path (#2279). - Electron's Settings -> Storage move writes the old voices root into the moved cache's voices_roots.json (fsync'd, best-effort, never fails the move). - voices_roots.json itself is published durably (flush, rename, dir flush); the swallowed write error is now an explained return (CodeQL). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs(changelog): merge duplicate Fixed section; credit #2279 highlight Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(longform): flush the cache directory after adopting a legacy entry or publishing voices_roots.json Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> | 2 天前 | |
Align CI fixtures with safe dubbing and compact Electron documentation | 8 天前 | |
Align CI fixtures with safe dubbing and compact Electron documentation | 8 天前 | |
fix(desktop): make recording and dubbing reliable (#1481) * fix(ui): keep scaled desktop shell responsive * fix(linux): support desktop microphone capture * fix(ui): update the centered VoiceStudio brand * fix(audio): fall back when recorder start is unsupported * fix(desktop): use the app header as titlebar * feat(audio): add live microphone input controls * fix(dub): recover from missing transcription models * fix(dub): make pipeline stages actionable * fix(asr): recover low-memory transcription * docs: record desktop reliability fixes * fix(ui): use semantic error banner border * fix(dub): harden recovery and recording fallbacks | 1 个月前 | |
fix: keep the backend alive on pre-Ampere NVIDIA GPUs (#2135) On a Tesla T4 the backend exited during the first /generate with no traceback and no HTTP response, leaving the client with RemoteDisconnected and every later call with ConnectionRefused. Three separate defects combined, which is why none of the reporter's workarounds helped. 1. torch.compile(mode="reduce-overhead") captures CUDA graphs. T4 (sm_75) passed the existing arch gate, so capture was attempted and aborted the process from inside the native CUDA library — below the interpreter, where neither the #278 eager-fallback wrapper nor any except clause can see it. The compile mode is now resolved per GPU: Ampere (sm_80) and newer keep the cudagraph mode, older cards drop to the non-cudagraph "default" mode and keep their compiled Inductor kernels. Fails open on any probe error, so no GPU that works today loses the optimization. OMNIVOICE_FORCE_CUDAGRAPH=1 restores it. 2. should_torch_compile() never read TORCH_COMPILE_DISABLE. main.py sets it on win32, build_engine_env injected it into subprocesses, and docs/install/windows.md tells users to export it — but the in-process gate ignored it, so the reporter exported the documented variable and still got "torch.compile applied". The gate now honours TORCH_COMPILE_DISABLE / TORCHDYNAMO_DISABLE / TORCHINDUCTOR_DISABLE on every platform, and an env opt-out on the parent propagates to engine subprocesses. The settings DB path is logged alongside the toggle: the reporter had three omnivoice.db files and edited one the backend never opened. 3. Settings -> Performance -> "Disable torch.compile" was rendered disabled outside Windows in both the Tauri and Electron UIs, so the one control that would have stopped this was unreachable for the affected Linux user. The toggle is now live on every platform, and build_engine_env honours it everywhere rather than only on win32. Also arms faulthandler before torch is imported, so a fatal native signal writes the faulting thread's Python stack to backend_err.log instead of the process vanishing silently. This does not prevent a crash; it makes one diagnosable. OMNIVOICE_DISABLE_FAULTHANDLER=1 skips it. Tests fail before / pass after, verified by stashing the source and running the new tests against unfixed code. The crash test kills a real child interpreter with a real SIGSEGV and requires a named Python frame in the output. test_torch_compile_path_gate's fixture now clears the compile-disable env vars: main.py setdefaults them on win32, so on a Windows runner they leaked into os.environ and decided those tests. Not verified on real hardware — no Turing GPU available. The sm_80 floor is inferred from the crash report and from docs/hardware-notes-tesla-t4.md, which already flagged cudagraphs on T4 as attempted by default and never evaluated. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> | 8 天前 | |
feat(integrations): guided Twilio setup and responsive integration pages (#2304) * feat(integrations): guided Twilio setup and responsive integration pages - Twilio detail page is a step-by-step checklist (account, tunnel, phone number, voice and behavior) with live status, per-step saves, exact cloudflared/ngrok commands for the OS and gateway port, copyable webhook URL, readiness rail, test card with explicit disabled reasons, recent calls and a "How it works" security explainer. Calls backend endpoints (/calls/settings, /calls/readiness) and the /calls route are feature-detected. - Detail pages: per-integration taglines from the registry, own category labels (no borrowed "Dubbing" key), one docs link, full-width scroller with a two-column container-query layout and sticky rail. - Select triggers always label their value (no raw __default__, auto, *, or locale codes); a source-scan test guards the class. - Catalog and featured logos open the in-app page, never a vendor website. - Gateway state exposes preferred_port so the tunnel command is exact before calls are turned on. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs(changelog): reference #2304 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(integrations): exact tunnel port and honest webhook status - preferred_port uses the same free-port probe as gateway start, so a taken base port no longer yields a tunnel command for the wrong service. - The phone-number step is Done only after a call that passed the signature check; rejected or busy attempts do not count. - Docs: Learn more applies to pages with a built-in setup. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs(changelog): list the #2304 docs update Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(i18n): phone step completes on a signed call; merge changelog Docs Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> | 1 天前 | |
chore: flatten project by moving all contents from submodule to root | 5 个月前 | |
fix(tts): reject unsupported languages across synthesis paths (#2219) Reject unsupported explicit languages before synthesis across direct and sidecar adapters; canonicalize picker labels and regional tags, preserve canonical codes for engine calls, and validate batch requests before output. Includes regression coverage and documentation. Thanks @rollroyces. | 5 天前 | |
Release VoiceStudio 5.0.0 (#1487) Complete the VoiceStudio identity, release documentation, assets, version mirrors, and safe cross-platform development startup. | 1 个月前 | |
Release VoiceStudio 5.0.0 (#1487) Complete the VoiceStudio identity, release documentation, assets, version mirrors, and safe cross-platform development startup. | 1 个月前 | |
Release VoiceStudio 5.0.0 (#1487) Complete the VoiceStudio identity, release documentation, assets, version mirrors, and safe cross-platform development startup. | 1 个月前 | |
ci: make Electron the only active desktop target (#2220) Make Electron the maintained desktop target, preserve frozen Tauri v0.5.3 updater feeds, and align setup, smoke checks, release policy and documentation. Validated by full CI, cross-platform smoke and install tests, security checks, and bot review. | 5 天前 | |
refactor(settings): modularize Settings page (1969→399 lines, all files under 500) (#758) * refactor(settings): extract Settings.jsx tabs into components/settings (1969→602 lines) Settings.jsx had grown to 1969 lines — every edit reloaded the whole file into context and risked unrelated breakage. This finishes the migration the existing components/settings/*Panel.jsx pattern started: the page is now a thin orchestrator and each heavy tab lives in its own file. Extracted (logic byte-for-byte identical; only import paths adjusted + the shared isTauri/askConfirm moved to components/settings/native.js): - GeneralTab, ModelStoreTab, EnginesTab, HotkeyTab, CredentialsTab - native.js — shared isTauri() wrapper + askConfirm() Tauri-dialog helper Also establishes the standard so files can't silently regrow: - CONTRIBUTING.md: frontend file-structure & size limits (soft 300 / hard 500) - eslint.config.js: warn-only max-lines:500 guardrail (CI stays green) - docs/maintenance-pages-modularization.md: the phased refactor plan Verified: vite build passes (all imports resolve); 18/18 settings tests pass; no new lint errors introduced (the pruned imports were the only regressions). Follow-ups (tracked in the plan doc): ModelStoreTab.jsx is 836 lines and Settings.jsx 602 — both still over the 500 cap (warn-only); split next. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(settings): split ModelStoreTab + Settings.jsx under the 500-line cap Follow-up to the tab extraction: bring the two remaining over-cap files into compliance with the new standard. Pure-mechanical, no behavior change. Settings.jsx 602 → 399: - Extract AboutTab, PrivacyTab, LogsTab into components/settings/ - Move the shared Row helper to components/settings/Row.jsx - LogsTab keeps its state in Settings() (lower-risk); About/Privacy take props ModelStoreTab.jsx 836 → 439, split into components/settings/models/: - format.js (fmtBytes/orgColor), runtime.js (computeRowRuntime) - columns.jsx exposes makeModelColumns(...) — a factory so the TanStack cell closures keep working; called with the same useMemo dep array as before - ModelsTable.jsx (virtualized table view), RecoBanner.jsx Every settings file is now under 500 lines. Verified: vite build passes; 18/18 settings tests pass; no new lint errors (the 4 remaining in Settings.jsx are pre-existing — refreshInfo no-op, a catch(e), two set-state-in-effect). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: mergetest <test@local> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> | 2 个月前 | |
fix(integrations): working MCP, Codex, API and Docker setups; honest catalog badges (#2289) * fix(mcp): serve /mcp without redirect, follow OMNIVOICE_PORT, real integration setups - /mcp and /mcp/ both reach the Streamable HTTP transport for every method, ahead of the SPA StaticFiles mount (POST /mcp was 405 on Docker/source builds, 307 without a built SPA). Regression test drives initialize -> tools/list -> DELETE on the real main.app with a dist dir and follow_redirects=False; the client-setup test no longer follows redirects. - MCP tool callbacks resolve the backend URL from OMNIVOICE_BIND_HOST + OMNIVOICE_PORT (OMNIVOICE_API_URL still overrides) instead of a hard-coded :3900; speech_client and the dev fallback redirect follow their port env too, with a class guard against literal :39xx URLs in backend code. - Integrations: setup registry keyed by slug drives the Works with VoiceStudio badge and capability chips; adds Codex CLI config.toml, generic MCP (HTTP + stdio shim), VoiceStudio API (curl + OpenAI SDK) and Docker/GHCR setups. Removes the fake category chips from the shared catalog config; fixes the duplicate Details headings. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test: pin capture path in speech envelope test; changelog refs (#2289) A prior lifespan-running test persists a sherpa dictation.model_id pref via the startup performance profile, routing the envelope test to the sherpa handler. Pin the capture path it asserts. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(integrations): export <base>/mcp/ for every MCP client The trailing-slash URL works on backends without the bare-/mcp fix too, so Claude Code, Cursor, Codex and the generic MCP card all export it. Docs lead with /mcp/ and note bare /mcp works on current backends. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(mcp): in-process tool callbacks; remote-safe stdio and API snippets Review findings on #2289: - Greptile P1: mounted MCP tools now call the backend app in-process via httpx.ASGITransport as a loopback caller, so a concrete LAN OMNIVOICE_BIND_HOST behind an API key / share PIN no longer 401s every tool. Standalone runs keep the HTTP backend_self_url() path. - Greptile P1: the stdio shim accepts OMNIVOICE_URL (https + path prefix) and forwards OMNIVOICE_API_KEY as a Bearer token; the MCP card exports the full base URL instead of host/port. - Greptile P1: remote API snippets read the key from $OMNIVOICE_API_KEY (curl Bearer header, Python os.environ) without exporting credentials. - CodeQL (Bandit B104): wildcard detection uses ipaddress.is_unspecified instead of a 0.0.0.0 literal. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(integrations): API keys only over https or loopback; reference them by env CodeRabbit findings on #2289: - Standalone MCP server and the stdio shim send OMNIVOICE_API_KEY as a Bearer token only to https or loopback targets (same rule as backend.speech_client); the shim refuses to start otherwise. - Remote https exports reference the key from the user's environment in each client's own syntax (Claude Code ${VAR}, Cursor ${env:VAR}, Codex bearer_token_env_var, curl/Python $OMNIVOICE_API_KEY); plain-http remotes export no key. - test_backend_self_url imports app modules inside the tests. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(integrations): credential guidance via translated hints; HTTP card auth line CodeRabbit findings on #2289: - The generic Streamable HTTP card lists the env-backed Authorization header for remote https backends. - English comments inside copyable snippets (API credentials, Docker GPU) move to translated hints (apiBearerHint, apiInsecureHint, dockerGpuHint, all 21 locales); a test forbids natural-language comments in snippets. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(integrations): PowerShell docker run; scheme-aware Agents SDK key CodeRabbit findings on #2289: - Docker/GHCR pages add a Windows PowerShell docker run (backtick continuations, CSPRNG key that works on PowerShell 5.1 and 7), so the default setup works on every platform. - The OpenAI Agents snippet only reads OMNIVOICE_API_KEY for loopback or https backends; a remote plain-http backend gets a placeholder. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(integrations): Agents SDK key only for remote https backends Greptile/CodeRabbit findings on #2289: the OpenAI Agents snippet now follows the shared remoteAuth policy exactly. It requires os.environ["OMNIVOICE_API_KEY"] for remote https backends, uses a placeholder on loopback (no key over plain http, even locally), and for a remote plain-http backend shows the translated 'use https' hint instead of implying the key will be sent. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test: drop the speech-platform capture pin now that #2294 isolates settings Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(integrations): remote https Python snippets tolerate an unkeyed backend Greptile finding on #2289: os.environ[...] raised KeyError on a remote https backend that runs without an API key. Read the key with a placeholder fallback (Agents SDK and API Python snippets); still loopback- and plain-http-safe via remoteAuth. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> | 2 天前 | |
fix: expose Ogg/Opus format for MCP speech files (#2324) Expose actual Ogg/Opus encoding for MCP speech files and URLs, with bounded per-render caching and remote-backend verification. Keep WAV defaults and protect audio paths. Fixes #2321. | 14 小时前 | |
fix(memory): release device cache across supported accelerators (#2317) * fix(memory): release the device cache on every accelerator the engines can use The dubbing and generation recovery paths open-coded the CUDA/MPS pair when flushing the device cache. Engines pick their device through torch.accelerator, so on an Ascend NPU or Intel XPU host those paths flushed nothing at all: the allocator kept the blocks the offload had just freed, and the next allocation failed with that memory still counted as in use. Extract the narrow primitive free_vram() already used (no gc.collect, no cuBLAS clear, covers CUDA/MPS/XPU/NPU, never raises) as release_device_cache() and call it from the five recovery paths. free_vram() keeps its gc + cuBLAS behaviour. Verified on an Ascend 910B4 (torch 2.15.0.dev + torch_npu 2.15.0.dev): reserved npu memory stayed at 134.0 MiB with the old pair and dropped to 0.0 MiB with the shared helper; the new tests fail 9/9 on the pre-change tree. * docs(changelog): credit the cache-flush fix with its PR ref (#2317) * fix(memory): follow the engines' accelerator and keep free_vram raising Two review findings on the cache-release helper: 1. On a hybrid host (CUDA probes as available, inference runs elsewhere) the elif chain flushed CUDA and never reached the active allocator. Ask the same question the engine sidecars ask -- torch.accelerator.current_accelerator( check_available=True) -- and flush that backend, falling back to the CUDA/MPS/XPU/NPU probe chain only when the build cannot answer. 2. free_vram() propagated empty_cache() failures before, and model_lifecycle unload callers report a failed flush to the user, so the helper takes raise_on_failure and free_vram() passes True. The direct recovery calls stay best-effort. Tests pin both, plus the cpu-answer and pre-2.6 fallbacks. * fix(memory): flush selected allocator and offload SSE cleanup * test(memory): remove source-text assertion * test(memory): trim obsolete test tail * fix(dub): flush MPS allocator after NLLB CPU fallback --------- Co-authored-by: Palash Debnath <4178343+debpalash@users.noreply.github.com> | 19 小时前 | |
feat: rename the product to VoiceStudio (previously OmniVoice-Studio) Renames what users see. The app, the installers, the window title, the docs and all 21 locales now say VoiceStudio, with "(previously OmniVoice-Studio)" noted near the title of each doc surface so people recognise it. Deliberately NOT renamed, because renaming any of them silently breaks an existing install — there is no legacy-path fallback anywhere in this codebase: - bundle identifier com.debpalash.omnivoice-studio (MSI UpgradeCode, macOS TCC grants, managed venv, WebView localStorage, the single-instance lock) - data directories OmniVoice / .omnivoice and omnivoice.db - the ~150 OMNIVOICE_* environment variables - the X-OmniVoice-* HTTP headers (a wire protocol) - the published Docker image paths - the OmniVoice ENGINE, which is a model name and not this product tests/test_identity_paths_survive_the_rename.py pins every one of those so a future well-meaning sweep cannot orphan a user's library. Linux .deb users install a new package name and should apt remove omnivoice-studio; that note is in the changelog. | 1 个月前 | |
refactor: codebase cleanup & root folder reorganization (#38) refactor: codebase cleanup & root folder reorganization | 4 个月前 | |
chore(release): prepare v0.5.2 (#1761) Synchronize VoiceStudio release metadata, lockfiles, installers, container references, documentation, and the dated v0.5.2 changelog after all planned fixes landed. | 23 天前 | |
feat(profiles): replace a saved clone's reference sample in place (#2285) * feat(profiles): replace a saved clone's reference sample in place (#2282) - PUT /profiles/{id}/audio stores the new clip under a versioned filename (invalidating path-keyed engine and chapter caches), validates extension and decodability, clears the locked take and own-voice consent, removes superseded files only after the DB commit, and rolls back on failure. - Profile records carry a cache-busting audio_url. - Electron profile editor gains Replace reference (upload/record, preview, keep current); the selected voice card gets an Edit voice button. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(profiles): atomic, verified, serialized reference replacement Addresses review findings on #2285: - Require a positive decode (libsndfile frames or an ffmpeg sample decode) before a clip replaces the working one; unverifiable clips return 422. - Stream uploads with a 128 MiB cap (413) instead of reading them whole. - Serialize replacements per profile and compare-and-swap the stored clip, so overlapping uploads never orphan a file. - Save name/style/language edits in the same request as the clip, so a failed upload leaves the whole profile unchanged. - Serve stored clips with their real media type. - Keep reference restores the pre-replacement transcript draft; stale duration probes can no longer replace a later pick; the recording timer goes through i18n. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(profiles): static replace SQL, reaped ffmpeg check, legacy NULL kind - One static UPDATE with COALESCE(?, column) for optional edits (no string-built SQL; clears the Bandit B608 finding). - The decode check runs through run_ffmpeg, which kills and reaps a stalled process on its 30 s timeout. - The compare-and-swap treats a NULL kind as clone, matching the read. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(profiles): reference decode check never queues on export slots run_ffmpeg waits for a shared FFmpeg slot before its timeout starts, so busy dub exports could stall a replacement indefinitely. Spawn the one-second decode directly with a bounded timeout, killing and reaping the process on any failure (cancellation included). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(profiles): cap reference decodes on their own slots, reap via finally - Reference checks get a dedicated 2-slot pool, separate from the dub export slots; one deadline bounds waiting for a slot plus the decode. - The decode's kill/reap runs in a finally block, so timeouts and request cancellation both clean up the process without catching BaseException. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> | 2 天前 | |
fix(security): replace persistent admin keys with scoped sessions (#1528) * fix(security): replace persistent admin keys with sessions Exchange the remote administrator key once for bounded, revocable credentials. Canonicalize backend principals, enforce cookie CSRF and exact origins, and use path-bound one-use WebSocket tickets. Migrate the bundled UI away from durable master-key storage and credential-bearing URLs. Add unit, integration, static-hygiene, and production-browser regressions plus synchronized operator documentation. * docs: link session hardening to PR 1528 * fix(security): key session indexes with process pepper Use HMAC-SHA-256 instead of an unkeyed digest for in-memory session and WebSocket-ticket indexes. This preserves constant-size lookup identifiers, makes copied records unusable without the process pepper, and resolves CodeQL's weak sensitive-data hash finding. * fix(auth): align empty bearer migration precedence Centralize the Authorization-channel presence decision with canonical principal parsing. Bearer followed only by spaces now remains an empty channel during legacy cookie migration, while unsupported or invalid explicit credentials stay authoritative and fail closed. * fix(security): harden admin session review boundaries * fix(security): derive key generations with HKDF * fix(auth): anchor the admin-session store so module reloads cannot fork it test_master_exchange_does_not_bypass_pin_on_normal_routes failed in full-suite runs: test_mcp_bindings' client fixture purges the services.* tree from sys.modules and reloads main, so api.routers.auth re-imported a fresh services.admin_sessions (new AdminSessionStore) while core.auth kept its import-time reference to the old one — the exchange issued the cookie into one store and the middleware resolved it against another, turning the expected "PIN required" into "API key required". Root cause is the class of bug, not the one test: a process-global auth store defined as a bare module-level singleton forks under importlib.reload or purge-and-reimport. Fix at the source: admin_session_store now resolves through a synthetic sys.modules anchor (_omnivoice_admin_session_store_anchor) that reloads never re-execute and package-prefix purges never match, so every copy of the module shares the one per-process store. No consumer or behavior changes. Regression test reproduces both fork vectors (in-place reload and sys.modules purge + fresh import) and asserts previously issued sessions still resolve and the store identity is preserved; it fails before this fix and passes after. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(auth): honor X-Forwarded-Proto for CSRF origin and Secure cookies behind TLS proxies Behind Tailscale Serve (docs/remote-gpu.md) or any TLS-terminating proxy, the browser talks https while the backend hop stays http, so exact-origin CSRF compared an https Origin against an http expectation and rejected every legitimate request, and the session cookie shipped without Secure. uvicorn's ProxyHeadersMiddleware only rewrites the scope for loopback peers, which misses Docker and any non-loopback proxy topology. New core.csrf.effective_scheme derives the client-facing scheme: resolved scope first (uvicorn's trusted-proxy rewrite wins), then an upgrade-only read of X-Forwarded-Proto's first value — https/wss promotes http to https, everything else is ignored, and a genuine TLS hop can never be downgraded. Used by both the destination-origin comparison and auth._secure_cookie so the WS-ticket/logout CSRF paths and the cookie Secure flag agree. Spoofing gains nothing: the host:port half of the origin tuple is untouched, browsers cannot attach the header cross-site without a preflight this API never grants, and forging it on plain http only adds Secure (the browser then drops the cookie — self-harm only). Regression tests: proxied https origin accepted (origin check, Secure flag, logout), comma-separated chains, scope-fallback path, spoofed header still rejects cross-origin, cannot downgrade real https, junk values ignored. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(auth): consume the stored admin key only after a successful exchange A remote-backend user upgrading with their backend unreachable lost the only stored copy of OMNIVOICE_API_KEY: every migration path deleted the durable ov_api_key BEFORE the session exchange settled, stranding them until they recovered the key from the server box. Close the whole class: - client.ts bootstrap: read the legacy key, exchange first, and remove the durable copy only after the exchange succeeds; on failure the key stays so the next launch retries the migration (auth gate still rises). - authSession.ts exchangeApiKey: move removeLegacyMaster from before the fetch to the cookie/bearer success paths — the key never coexists with a live session, but a rejected or hung exchange no longer consumes it. - remoteBackendProbe.ts configuredRemoteBackend: stop wiping the key on every app mount. - RemoteBackendPanel: a connection test or an aborted save no longer wipes the pending key; only disabling the remote backend discards it. - prefKeys.js: ov_api_key moves from PREF_KEYS to PRESERVED_KEYS — factory reset preserves the pending connection credential exactly like ov_backend_url; the successful migration is what deletes it. Tighten the credential-hygiene static guard to match: it accepted sessionStorage.setItem('ov_api_key', …) — the exact class it exists to close. The guard now flags .setItem(<master key>) on any storage receiver, quote style, or injected-store alias, with a self-test pinning what it catches and what stays legal. Fail-before/pass-after regression tests: backend unreachable retains the key and the next bootstrap retries it; a successful exchange removes it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * perf(auth): make session validation occupancy-independent * test(auth): catch optional master-key storage calls * feat(docs): add PR control document for bultodepapas in VoiceStudio * docs: keep the PR tracking board in the fork; credit the changelog line The pr-control document is excellent process discipline, but it is the contributor's own operational board (their inventory, their update commands) — it lives naturally in their fork, and docs/agents/ here is context every repo agent loads. Removed with appreciation; the changelog line gains its contributor credit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: debpalash <4178343+debpalash@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> | 1 个月前 | |
Keep read-only telemetry outside worker drain and shutdown gates | 8 天前 | |
feat: setup wizard, donate page, CI fixes, performance optimizations, and style extraction - Implement donate page and migrate API fetching to react-query hooks - Add setup wizard for batch job management and voice clip editing - Refactor setup router into package (wizard, models, download sub-modules) - Fix 9 CI test failures from setup router refactor - Fix cross-device link error in prefs.py atomic writes - Fix event loop mismatch in export test fixtures - Modernize README with architecture diagram and 13 app screenshots - Defer per-segment disk writes in dub_generate for ~6s faster dubs - Extract 45 inline styles from Launchpad, KeyboardCheatsheet, DubSegmentRow - Add playwright dev dep and screenshot capture script | 4 个月前 | |
docs(readme): Opal-style restyle + fresh v0.3.9 screenshots (#937) - Emoji section headers with explicit <a id> anchors. Emoji breaks GitHub's auto-generated heading slugs, so every in-page nav target keeps a stable explicit anchor (verified all href="#..." resolve). - Refresh the screenshot gallery. The prior set was from April, predating the launchpad / settings / dictation UI overhaul, so it misrepresented the app. Captured fresh at retina from the live v0.3.9 UI and led the gallery with the new Launchpad home: launchpad, studio, voice design, voice gallery, dubbing, engine-compatibility matrix, model store, embedded API reference (Scalar), and the in-app changelog reader. - Fix the stale engine count (11 -> 14 TTS engines) in the comparison table, FAQ, and roadmap to match the engine table + backend registry. - Use <kbd> keycaps for the dictation shortcut (Opal detail). Co-authored-by: mergetest <test@local> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> | 2 个月前 | |
docs(readme): charm + organization overhaul (Opal-style) — collapsibles + OpenAI-compatible API section (#945) * docs(readme): charm + organization overhaul (Opal-style) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(readme): restore inventory-exact feature names (docs-drift guard) The charm pass sentence-cased five bold leads in the collapsed feature list; scripts/check-docs-drift.py greps for the inventory's exact title-case names. Restored: Vocal Isolation, Speaker Diarization, Batch Queue, AI Watermark, GPU Auto-Detect. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(readme): dubbing screenshot shows a real completed dub (37 segs, EN→BN) Replaces the empty drop-zone shot with the populated editor — video + waveform + cast, 37 Bengali segment rows, DUB COMPLETE banner — captured live from the v0.3.9 app; caption updated to match. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: mergetest <test@local> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> | 2 个月前 | |
docs(readme): Opal-style restyle + fresh v0.3.9 screenshots (#937) - Emoji section headers with explicit <a id> anchors. Emoji breaks GitHub's auto-generated heading slugs, so every in-page nav target keeps a stable explicit anchor (verified all href="#..." resolve). - Refresh the screenshot gallery. The prior set was from April, predating the launchpad / settings / dictation UI overhaul, so it misrepresented the app. Captured fresh at retina from the live v0.3.9 UI and led the gallery with the new Launchpad home: launchpad, studio, voice design, voice gallery, dubbing, engine-compatibility matrix, model store, embedded API reference (Scalar), and the in-app changelog reader. - Fix the stale engine count (11 -> 14 TTS engines) in the comparison table, FAQ, and roadmap to match the engine table + backend registry. - Use <kbd> keycaps for the dictation shortcut (Opal detail). Co-authored-by: mergetest <test@local> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> | 2 个月前 | |
docs(readme): Opal-style restyle + fresh v0.3.9 screenshots (#937) - Emoji section headers with explicit <a id> anchors. Emoji breaks GitHub's auto-generated heading slugs, so every in-page nav target keeps a stable explicit anchor (verified all href="#..." resolve). - Refresh the screenshot gallery. The prior set was from April, predating the launchpad / settings / dictation UI overhaul, so it misrepresented the app. Captured fresh at retina from the live v0.3.9 UI and led the gallery with the new Launchpad home: launchpad, studio, voice design, voice gallery, dubbing, engine-compatibility matrix, model store, embedded API reference (Scalar), and the in-app changelog reader. - Fix the stale engine count (11 -> 14 TTS engines) in the comparison table, FAQ, and roadmap to match the engine table + backend registry. - Use <kbd> keycaps for the dictation shortcut (Opal detail). Co-authored-by: mergetest <test@local> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> | 2 个月前 | |
chore: bump to 0.5.0 (#1540) * chore: bump to 0.5.0 Owner-requested minor bump. package.json is the source of truth; the three mirrors (Cargo.toml, pyproject.toml, _FALLBACK_VERSION), the three lockfiles and the branding pin move in lockstep, and the accumulated Unreleased section becomes the curated 0.5.0 release notes — quiet Highlights first, one-liner subsections after, duplicates folded. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: fresh README for the VoiceStudio era; 0.5.0 notes wear the release README: 551 lines from 656 — a What's-new-in-0.5.0 section with real captures, the engine tables corrected to the actual 16 TTS registrations, a stale Settings path and a broken Colab link fixed, roadmap/FAQ/credits trimmed to what earns its place. Release notes: the quick-switch GIF and catalogue/gallery screenshots, captured from the running app during the pre-bump test pass, embedded after the Highlights; #1542's gallery work and the ffmpeg CI fallback recorded in their subsections. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: the feature inventory's Remote Model Downloads mention survives the README trim check-docs-drift requires every docs/features.yaml name verbatim in the README; the overhaul folded the phrase away. It now lives in the remote workers feature line. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: one blockquote, and an architecture claim that survives the opt-ins CodeRabbit on #1540: MD028 blank line inside adjacent blockquotes, and 'every layer is on your machine' contradicted the opt-in remote paths documented two sections away — it now states local-by-default with the opt-ins named. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> | 1 个月前 | |
feat: setup wizard, donate page, CI fixes, performance optimizations, and style extraction - Implement donate page and migrate API fetching to react-query hooks - Add setup wizard for batch job management and voice clip editing - Refactor setup router into package (wizard, models, download sub-modules) - Fix 9 CI test failures from setup router refactor - Fix cross-device link error in prefs.py atomic writes - Fix event loop mismatch in export test fixtures - Modernize README with architecture diagram and 13 app screenshots - Defer per-segment disk writes in dub_generate for ~6s faster dubs - Extract 45 inline styles from Launchpad, KeyboardCheatsheet, DubSegmentRow - Add playwright dev dep and screenshot capture script | 4 个月前 | |
feat: setup wizard, donate page, CI fixes, performance optimizations, and style extraction - Implement donate page and migrate API fetching to react-query hooks - Add setup wizard for batch job management and voice clip editing - Refactor setup router into package (wizard, models, download sub-modules) - Fix 9 CI test failures from setup router refactor - Fix cross-device link error in prefs.py atomic writes - Fix event loop mismatch in export test fixtures - Modernize README with architecture diagram and 13 app screenshots - Defer per-segment disk writes in dub_generate for ~6s faster dubs - Extract 45 inline styles from Launchpad, KeyboardCheatsheet, DubSegmentRow - Add playwright dev dep and screenshot capture script | 4 个月前 | |
docs(readme): Opal-style restyle + fresh v0.3.9 screenshots (#937) - Emoji section headers with explicit <a id> anchors. Emoji breaks GitHub's auto-generated heading slugs, so every in-page nav target keeps a stable explicit anchor (verified all href="#..." resolve). - Refresh the screenshot gallery. The prior set was from April, predating the launchpad / settings / dictation UI overhaul, so it misrepresented the app. Captured fresh at retina from the live v0.3.9 UI and led the gallery with the new Launchpad home: launchpad, studio, voice design, voice gallery, dubbing, engine-compatibility matrix, model store, embedded API reference (Scalar), and the in-app changelog reader. - Fix the stale engine count (11 -> 14 TTS engines) in the comparison table, FAQ, and roadmap to match the engine table + backend registry. - Use <kbd> keycaps for the dictation shortcut (Opal detail). Co-authored-by: mergetest <test@local> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> | 2 个月前 | |
docs(readme): Opal-style restyle + fresh v0.3.9 screenshots (#937) - Emoji section headers with explicit <a id> anchors. Emoji breaks GitHub's auto-generated heading slugs, so every in-page nav target keeps a stable explicit anchor (verified all href="#..." resolve). - Refresh the screenshot gallery. The prior set was from April, predating the launchpad / settings / dictation UI overhaul, so it misrepresented the app. Captured fresh at retina from the live v0.3.9 UI and led the gallery with the new Launchpad home: launchpad, studio, voice design, voice gallery, dubbing, engine-compatibility matrix, model store, embedded API reference (Scalar), and the in-app changelog reader. - Fix the stale engine count (11 -> 14 TTS engines) in the comparison table, FAQ, and roadmap to match the engine table + backend registry. - Use <kbd> keycaps for the dictation shortcut (Opal detail). Co-authored-by: mergetest <test@local> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> | 2 个月前 | |
docs(readme): Opal-style restyle + fresh v0.3.9 screenshots (#937) - Emoji section headers with explicit <a id> anchors. Emoji breaks GitHub's auto-generated heading slugs, so every in-page nav target keeps a stable explicit anchor (verified all href="#..." resolve). - Refresh the screenshot gallery. The prior set was from April, predating the launchpad / settings / dictation UI overhaul, so it misrepresented the app. Captured fresh at retina from the live v0.3.9 UI and led the gallery with the new Launchpad home: launchpad, studio, voice design, voice gallery, dubbing, engine-compatibility matrix, model store, embedded API reference (Scalar), and the in-app changelog reader. - Fix the stale engine count (11 -> 14 TTS engines) in the comparison table, FAQ, and roadmap to match the engine table + backend registry. - Use <kbd> keycaps for the dictation shortcut (Opal detail). Co-authored-by: mergetest <test@local> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> | 2 个月前 | |
docs(readme): Opal-style restyle + fresh v0.3.9 screenshots (#937) - Emoji section headers with explicit <a id> anchors. Emoji breaks GitHub's auto-generated heading slugs, so every in-page nav target keeps a stable explicit anchor (verified all href="#..." resolve). - Refresh the screenshot gallery. The prior set was from April, predating the launchpad / settings / dictation UI overhaul, so it misrepresented the app. Captured fresh at retina from the live v0.3.9 UI and led the gallery with the new Launchpad home: launchpad, studio, voice design, voice gallery, dubbing, engine-compatibility matrix, model store, embedded API reference (Scalar), and the in-app changelog reader. - Fix the stale engine count (11 -> 14 TTS engines) in the comparison table, FAQ, and roadmap to match the engine table + backend registry. - Use <kbd> keycaps for the dictation shortcut (Opal detail). Co-authored-by: mergetest <test@local> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> | 2 个月前 | |
feat: rename the product to VoiceStudio (previously OmniVoice-Studio) Renames what users see. The app, the installers, the window title, the docs and all 21 locales now say VoiceStudio, with "(previously OmniVoice-Studio)" noted near the title of each doc surface so people recognise it. Deliberately NOT renamed, because renaming any of them silently breaks an existing install — there is no legacy-path fallback anywhere in this codebase: - bundle identifier com.debpalash.omnivoice-studio (MSI UpgradeCode, macOS TCC grants, managed venv, WebView localStorage, the single-instance lock) - data directories OmniVoice / .omnivoice and omnivoice.db - the ~150 OMNIVOICE_* environment variables - the X-OmniVoice-* HTTP headers (a wire protocol) - the published Docker image paths - the OmniVoice ENGINE, which is a model name and not this product tests/test_identity_paths_survive_the_rename.py pins every one of those so a future well-meaning sweep cannot orphan a user's library. Linux .deb users install a new package name and should apt remove omnivoice-studio; that note is in the changelog. | 1 个月前 | |
fix(sharing): bundle LAN frontend in desktop installs | 1 个月前 | |
fix(integrations): working MCP, Codex, API and Docker setups; honest catalog badges (#2289) * fix(mcp): serve /mcp without redirect, follow OMNIVOICE_PORT, real integration setups - /mcp and /mcp/ both reach the Streamable HTTP transport for every method, ahead of the SPA StaticFiles mount (POST /mcp was 405 on Docker/source builds, 307 without a built SPA). Regression test drives initialize -> tools/list -> DELETE on the real main.app with a dist dir and follow_redirects=False; the client-setup test no longer follows redirects. - MCP tool callbacks resolve the backend URL from OMNIVOICE_BIND_HOST + OMNIVOICE_PORT (OMNIVOICE_API_URL still overrides) instead of a hard-coded :3900; speech_client and the dev fallback redirect follow their port env too, with a class guard against literal :39xx URLs in backend code. - Integrations: setup registry keyed by slug drives the Works with VoiceStudio badge and capability chips; adds Codex CLI config.toml, generic MCP (HTTP + stdio shim), VoiceStudio API (curl + OpenAI SDK) and Docker/GHCR setups. Removes the fake category chips from the shared catalog config; fixes the duplicate Details headings. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test: pin capture path in speech envelope test; changelog refs (#2289) A prior lifespan-running test persists a sherpa dictation.model_id pref via the startup performance profile, routing the envelope test to the sherpa handler. Pin the capture path it asserts. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(integrations): export <base>/mcp/ for every MCP client The trailing-slash URL works on backends without the bare-/mcp fix too, so Claude Code, Cursor, Codex and the generic MCP card all export it. Docs lead with /mcp/ and note bare /mcp works on current backends. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(mcp): in-process tool callbacks; remote-safe stdio and API snippets Review findings on #2289: - Greptile P1: mounted MCP tools now call the backend app in-process via httpx.ASGITransport as a loopback caller, so a concrete LAN OMNIVOICE_BIND_HOST behind an API key / share PIN no longer 401s every tool. Standalone runs keep the HTTP backend_self_url() path. - Greptile P1: the stdio shim accepts OMNIVOICE_URL (https + path prefix) and forwards OMNIVOICE_API_KEY as a Bearer token; the MCP card exports the full base URL instead of host/port. - Greptile P1: remote API snippets read the key from $OMNIVOICE_API_KEY (curl Bearer header, Python os.environ) without exporting credentials. - CodeQL (Bandit B104): wildcard detection uses ipaddress.is_unspecified instead of a 0.0.0.0 literal. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(integrations): API keys only over https or loopback; reference them by env CodeRabbit findings on #2289: - Standalone MCP server and the stdio shim send OMNIVOICE_API_KEY as a Bearer token only to https or loopback targets (same rule as backend.speech_client); the shim refuses to start otherwise. - Remote https exports reference the key from the user's environment in each client's own syntax (Claude Code ${VAR}, Cursor ${env:VAR}, Codex bearer_token_env_var, curl/Python $OMNIVOICE_API_KEY); plain-http remotes export no key. - test_backend_self_url imports app modules inside the tests. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(integrations): credential guidance via translated hints; HTTP card auth line CodeRabbit findings on #2289: - The generic Streamable HTTP card lists the env-backed Authorization header for remote https backends. - English comments inside copyable snippets (API credentials, Docker GPU) move to translated hints (apiBearerHint, apiInsecureHint, dockerGpuHint, all 21 locales); a test forbids natural-language comments in snippets. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(integrations): PowerShell docker run; scheme-aware Agents SDK key CodeRabbit findings on #2289: - Docker/GHCR pages add a Windows PowerShell docker run (backtick continuations, CSPRNG key that works on PowerShell 5.1 and 7), so the default setup works on every platform. - The OpenAI Agents snippet only reads OMNIVOICE_API_KEY for loopback or https backends; a remote plain-http backend gets a placeholder. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(integrations): Agents SDK key only for remote https backends Greptile/CodeRabbit findings on #2289: the OpenAI Agents snippet now follows the shared remoteAuth policy exactly. It requires os.environ["OMNIVOICE_API_KEY"] for remote https backends, uses a placeholder on loopback (no key over plain http, even locally), and for a remote plain-http backend shows the translated 'use https' hint instead of implying the key will be sent. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test: drop the speech-platform capture pin now that #2294 isolates settings Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(integrations): remote https Python snippets tolerate an unkeyed backend Greptile finding on #2289: os.environ[...] raised KeyError on a remote https backend that runs without an API key. Read the key with a placeholder fallback (Agents SDK and API Python snippets); still loopback- and plain-http-safe via remoteAuth. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> | 2 天前 | |
fix(integrations): footer logos open the in-app integration page (#2302) * fix(integrations): footer logos open the in-app integration page Clicking a footer logo launched the vendor's website. It now opens that integration's page in the app (the catalog page when there is no detail page); the website link stays on the detail page. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs(changelog): reference #2302 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs(changelog): reference #2302 with a Highlights block Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> | 1 天前 | |
feat: rename the product to VoiceStudio (previously OmniVoice-Studio) Renames what users see. The app, the installers, the window title, the docs and all 21 locales now say VoiceStudio, with "(previously OmniVoice-Studio)" noted near the title of each doc surface so people recognise it. Deliberately NOT renamed, because renaming any of them silently breaks an existing install — there is no legacy-path fallback anywhere in this codebase: - bundle identifier com.debpalash.omnivoice-studio (MSI UpgradeCode, macOS TCC grants, managed venv, WebView localStorage, the single-instance lock) - data directories OmniVoice / .omnivoice and omnivoice.db - the ~150 OMNIVOICE_* environment variables - the X-OmniVoice-* HTTP headers (a wire protocol) - the published Docker image paths - the OmniVoice ENGINE, which is a model name and not this product tests/test_identity_paths_survive_the_rename.py pins every one of those so a future well-meaning sweep cannot orphan a user's library. Linux .deb users install a new package name and should apt remove omnivoice-studio; that note is in the changelog. | 1 个月前 | |
feat(electron): add full VoiceStudio desktop app | 10 天前 | |
fix(gallery): calibrate preview guard against shipped speech fixtures | 18 天前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 10 天前 | ||
| 1 个月前 | ||
| 23 小时前 | ||
| 18 小时前 | ||
| 6 天前 | ||
| 10 小时前 | ||
| 1 天前 | ||
| 8 天前 | ||
| 2 天前 | ||
| 1 个月前 | ||
| 17 天前 | ||
| 10 天前 | ||
| 15 天前 | ||
| 5 天前 | ||
| 10 小时前 | ||
| 21 天前 | ||
| 1 天前 | ||
| 1 天前 | ||
| 2 天前 | ||
| 1 个月前 | ||
| 10 天前 | ||
| 1 天前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 5 个月前 | ||
| 5 天前 | ||
| 14 天前 | ||
| 10 天前 | ||
| 10 天前 | ||
| 17 小时前 | ||
| 10 天前 | ||
| 10 天前 | ||
| 4 天前 | ||
| 10 天前 | ||
| 17 小时前 | ||
| 9 天前 | ||
| 5 天前 | ||
| 6 天前 | ||
| 8 天前 | ||
| 10 天前 | ||
| 4 天前 | ||
| 10 天前 | ||
| 6 天前 | ||
| 3 天前 | ||
| 10 天前 | ||
| 5 天前 | ||
| 10 天前 | ||
| 10 天前 | ||
| 16 天前 | ||
| 1 个月前 | ||
| 2 天前 | ||
| 8 天前 | ||
| 8 天前 | ||
| 1 个月前 | ||
| 8 天前 | ||
| 1 天前 | ||
| 5 个月前 | ||
| 5 天前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 5 天前 | ||
| 2 个月前 | ||
| 2 天前 | ||
| 14 小时前 | ||
| 19 小时前 | ||
| 1 个月前 | ||
| 4 个月前 | ||
| 23 天前 | ||
| 2 天前 | ||
| 1 个月前 | ||
| 8 天前 | ||
| 4 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 1 个月前 | ||
| 4 个月前 | ||
| 4 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 2 天前 | ||
| 1 天前 | ||
| 1 个月前 | ||
| 10 天前 | ||
| 18 天前 |