Repository navigation
v1.5.0: UI redesign, issue #19 fixes, Linux audio fix - #20
Conversation
cpython-3.12.13 from python-build-standalone ships libpython with GNU_STACK RWE flag, which Linux 6.8+ kernels reject. Python 3.13 builds do not have this flag.
python-build-standalone ships libpython with GNU_STACK RWE flag which Linux 6.8+ kernels reject. Revert to Python 3.12 and use execstack -c to clear the flag after PyInstaller bundles the app.
sounddevice loads libportaudio.so at runtime via ctypes. On Arch this is pre-installed, but on Ubuntu 22.04 CI it's missing, so PyInstaller never bundles it and audio devices fail to open.
Ubuntu 22.04's PortAudio only has the ALSA backend, so the bundled library only sees raw hw: devices which don't support 16kHz. The system's PortAudio on modern Linux has PipeWire/PulseAudio backends that handle sample rate conversion and show all virtual devices.
Some audio devices (raw ALSA hw: devices, or when PipeWire ALSA plugin isn't available) don't support 16kHz natively. Now tries 16kHz first, falls back to the device's default rate, and resamples to 16kHz for Whisper using linear interpolation.
model_manager: fix DownloadProgressBar so byte progress reports during multi-GB downloads. tqdm with disable=None auto-disables when stderr isn't a TTY (every packaged GUI build), which silently drops self.n increments and self.unit. That made big models look frozen at 0% for minutes - the "won't download" complaint. Track bytes via _vf_n counter and force disable=False. Real-network test confirms base (145MB) now reports 9 smooth byte updates vs 5 file-count jumps. model_manager: add get_cache_dir() so the UI can surface the resolved HF cache path. hotkey: add manual_start/manual_stop and get_status(). manual_start reuses the toggle-mode bookkeeping so transcription, paste, and history behave identically to a hotkey-driven session. get_status surfaces evdev permission errors when the user isn't in the input group on Wayland - silent failures previously made hotkeys appear broken. app_controller: manual_toggle_recording wraps the hotkey activate/ deactivate flow. server: open_external_url uses QDesktopServices.openUrl first, then non-blocking subprocess.Popen. The previous subprocess.run with check=True failed on KDE Plasma because xdg-open forks to kde-open5 and exits non-zero even on success, breaking "Report Issue" and "Star on GitHub" links. server: expose manual_toggle_recording, get_recording_state, get_hotkey_status, get_model_cache_dir, open_model_cache_dir; add api.ts wrappers. tests: add real-network download tests gated on VOICEFLOW_NETWORK_TESTS=1 (tiny + base, ~71s) and big-model tests on VOICEFLOW_BIG_MODEL_TESTS=1 (turbo). White-box regression test verifies _vf_n counter works when tqdm is disabled. tests(audio): reference TARGET_SAMPLE_RATE - the attr was renamed in d5ecc49 when the audio service gained the device-rate fallback. pyproject: add pytest network/big_model markers.
Comprehensive UI overhaul aligning the app with an editorial "engineering
manifest" voice — flat surfaces, hairline dividers, mono accents, and
chapter-marker section eyebrows replace the previous bento-card grid.
Pages:
- SettingsTab: spec-sheet model picker (size/VRAM/speed/accuracy dots),
segmented retention, 3-chip theme picker, GPU manifest panel, full
danger-zone redesign
- HomePage: log-row layout (time + text + hover actions) replaces the
card grid; StatsHeader rebuilt as 4-stat manifest with today vs
lifetime cuts
- HistoryPage: full redesign matching HomePage's log aesthetic with a
mono "searching..." indicator for server-side search
- Onboarding: 7 steps cleaned of glass-card/rounded-2xl/tinted-icon-square
patterns; cross-platform copy ("Launch at login" replaces Windows-only
text); cuDNN download flow refined
- Dashboard shell: mobile header brandmark aligned with desktop sidebar;
HotkeyStatusBanner pinned (no longer scrolls with content)
- Sidebar: eyebrow tracking aligned to manifest convention
- ModelDownloadModal: shadcn defaults instead of glass-strong shim
Theme:
- Dark mode is now the default across index.html, settings.py defaults,
and Onboarding initial state
- Removed legacy glass-card/glass-strong/rounded-xl-2xl-3xl chrome
- Standardized on rounded-md/lg radius tokens
- Mono accents use JetBrains Mono with tracking-[0.25em] eyebrows
Cleanup:
- Deleted dead HistoryTab.tsx
- Removed 6 outdated marketing screenshots; added 3 new (dashboard,
onboarding, model-picker) showing the redesigned UI
- README hero now opens with the actual app dashboard
Bumps version to 1.5.0 across package.json, pyproject.toml,
installer/voiceflow.iss, src/lib/constants.ts, and the sidebar footer.
CI's stricter TypeScript caught a mismatch between my validateHotkey callback (returning error?: string) and HotkeyCapture's onValidate prop (expecting error: string | null). Add explicit return type and update the HotkeysPanel/HotkeyMode prop signatures to match.
…oject metadata - pyproject.toml: rewrite description, add keywords, classifiers, project URLs - VoiceFlow.desktop: add GenericName, Keywords, expand Categories - voiceflow.iss: replace placeholder URL with get-voice-flow.vercel.app, split support/updates URLs - AppStream metainfo for Linux app store indexing (Flathub/GNOME Software/KDE Discover) - README: new SEO opening line, promote website link, drop hardcoded v1.3.1 to /releases/latest - site.webmanifest: add description, dark theme/background colors - index.html: add description meta + theme-color
macOS still works unofficially but isn't an officially supported platform yet. Removed macOS from public-facing descriptions across pyproject, .desktop, AppStream metainfo, README, site.webmanifest, and bundled index.html. Also rewrote descriptions to drop AI-flavored patterns (em-dash overuse, rule-of-three chants, promotional triplets like "no cloud, no telemetry, no subscription") in favor of plainer wording.
ctranslate2 4.x has no Linux init code that adds the nvidia-cublas-cu12 package's lib dir to the dynamic linker path, so libcublas.so.12 was unloadable in both the venv and the AppImage — silently falling back to CPU even when CUDA was technically available. Add _preload_nvidia_libs() that imports the nvidia namespace package and ctypes.CDLL each .so under nvidia/<pkg>/lib/ with RTLD_GLOBAL. This makes the symbols globally visible so libctranslate2's dlopen() resolves them. Also add --collect-all=nvidia to the Linux PyInstaller invocation so the nvidia pip packages actually ship in the AppImage.
A prior edit inserted [project.urls] before requires-python and dependencies, silently nesting them under [project.urls]. uv warned 'No requires-python value found in the workspace' and skipped installing pyloid, breaking both Linux and Windows CI builds. Restore correct TOML structure (all [project] fields first, then [project.urls]) and regenerate uv.lock against the fixed manifest.
…ound Bundled libasound has its ALSA plugin search path hardcoded to the build host's path (Ubuntu CI: /usr/lib/x86_64-linux-gnu/alsa-lib). On other distros (Arch: /usr/lib/alsa-lib) this path doesn't exist, so libasound can't load libasound_module_pcm_pipewire.so / pulse plugin and PortAudio silently reports zero virtual input devices — the recurring 'no mics in build' bug. Removing _internal/libasound* makes the loader fall through to the user's system libasound, which knows its own plugin layout. Do NOT delete av.libs/libasound-cfbebb71.so.2.0.0 — PyAV's libavdevice has that exact name in its NEEDED list (different SONAME, doesn't conflict with PortAudio's libasound.so.2 lookup). Removing it crashes startup with ImportError on libasound-cfbebb71.
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (10)
📒 Files selected for processing (33)
📝 WalkthroughWalkthroughVersion 1.5.0 release: extends Linux support with ALSA bundling cleanup and NVIDIA CUDA preloading, introduces UI-driven recording control and hotkey status monitoring via new RPC endpoints, significantly refactors React components (history, home, settings, popup, onboarding) with new internal layouts, updates project metadata across multiple formats, and improves model download progress reporting and default theming. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Review rate limit: 0/1 reviews remaining, refill in 60 minutes.Comment |
Summary
Root cause of the recurring 'no mics in build' bug
Bundled libasound has its ALSA plugin search path hardcoded at build time to the build host's path (Ubuntu CI: `/usr/lib/x86_64-linux-gnu/alsa-lib`). On other distros (Arch: `/usr/lib/alsa-lib`) the plugin path doesn't exist, so libasound can't load `libasound_module_pcm_pipewire.so` or the pulse plugin → PortAudio reports zero PipeWire/Pulse-routed input devices. Removing `_internal/libasound*` makes the loader fall through to the user's system libasound, which knows where its own plugins live.
Test plan
Summary by CodeRabbit
New Features
Enhancements
Version Update