Commit Graph
163 Commits
Author SHA1 Message Date
Jatin K MalikandGitHub 844d2fb104 fix(install): ensure whisper module is properly installed with --auto flag (#205)
When installing with --engine=whisper, the installer would continue even
if the whisper package installation failed, creating a config file with
engine=whisper. This caused the app to crash on startup with
'No module named whisper'.

Changes:
- Add proper verification of whisper installation by importing the module
- Only create whisper config if installation succeeds
- Fall back to whisper.cpp if whisper installation fails
- Provide clear error messages during installation

Fixes #190
2026-02-12 17:50:50 -08:00
Jatin K MalikandGitHub 8b4a1b2f50 fix(audio): resolve PyAudio paInt16 attribute error on reconnection (#204)
The _attempt_audio_reconnection method was incorrectly accessing
paInt16 as an attribute of the PyAudio instance instead of the
pyaudio module. Added local import and fixed the reference.

Fixes #203
2026-02-12 17:46:51 -08:00
Jatin K MalikandGitHub 1e0a2a6cee chore(release): prepare v0.6.1-beta (#201)
Bump version from 0.6.0-beta to 0.6.1-beta with installation improvements:

Version Updates:
- src/vocalinux/version.py: 0.6.0-beta → 0.6.1-beta
- install.sh: Default tag and help text updated
- web/package.json: 0.6.0 → 0.6.1
- web/src/app/layout.tsx: schema.org softwareVersion updated
- web/src/app/page.tsx: version badge updated

Documentation Updates:
- README.md: New 'What's New' section for v0.6.1-beta
- docs/UPDATE.md: Added v0.6.1-beta release notes with new features
- docs/INSTALL.md: Version references updated
- docs/RELEASE_PROCESS.md: Example commands updated
- tests/distro-testing-checklist.md: Version references updated
- src/vocalinux/main.py: Error message updated

New Features in v0.6.1-beta:
- Interactive backend selection for whisper.cpp (GPU vs CPU)
- Enhanced welcome message with testing instructions
- Simplified install commands (tag-based URLs)
- Better GPU support with proper library detection

Bug Fixes:
- Fixed bash arithmetic with set -e
- Fixed TTY detection for interactive mode
- Auto-install git if missing
- Fixed GPU installation commands
2026-02-12 13:12:21 -08:00
Jatin K MalikandGitHub 86ee79cc0d chore: update install commands to use tag-based URLs (#200)
Changed install commands to download install.sh directly from the release
tag instead of from main branch with --tag parameter. This ensures:

1. The install script version matches the release being installed
2. No version mismatch between script and code
3. Simpler, cleaner install commands

Changes:
- install.sh: Updated error message to use v0.6.0-beta URL
- README.md: All install commands now use v0.6.0-beta/install.sh
- docs/INSTALL.md: Updated quick install command
- docs/UPDATE.md: Updated update command examples
- docs/RELEASE_PROCESS.md: Updated example command
- src/vocalinux/main.py: Updated error message install command
- tests/distro-testing-checklist.md: Updated download URL
- web/src/app/page.tsx: Now uses dynamic tag in URL (not main)
- .github/workflows/release.yml: Release notes use tag-based URL

Before:
  curl .../main/install.sh | bash -s -- --tag=v0.6.0-beta

After:
  curl .../v0.6.0-beta/install.sh | bash

Fixes version consistency between install script and installed code.
2026-02-12 13:02:51 -08:00
Jatin K MalikandGitHub 091731e7ca feat(install): add backend selection and enhanced welcome message (#197)
Add interactive whisper.cpp backend selection:
- New Step 3: Choose between GPU (Vulkan/CUDA) or CPU backend
- Auto-detects available GPU capabilities and recommends best option
- Shows helpful tips when GPU libraries are missing
- Respects user's backend choice during installation
- Installation summary now shows backend selection

Enhanced welcome message at end:
- Shows what was installed (engine, backend, locations)
- Clear testing instructions with example
- Voice command examples
- Management commands (start, debug, GUI)
- Better formatting with visual separators

Updated system dependencies:
- Added glslc package for Vulkan shader compilation
- Fixed package name from glslang-tools to glslc
- Updated all distro package lists (Ubuntu, Debian, Fedora, Arch, openSUSE)
- Improved error messages when GPU builds fail

Fixed bash arithmetic issues:
- Replaced ((var++)) with 1 for set -e compatibility

PR: https://github.com/jatinkrmalik/vocalinux/pull/197
2026-02-12 12:43:51 -08:00
Jatin K MalikandGitHub 1a166eff56 fix(install): execute GPU pip command directly, not via variable (#196)
The previous fix stored the pip command in a variable:
  PYWHISPERCPP_INSTALL_CMD="GGML_CUDA=1 pip install ..."
  $PYWHISPERCPP_INSTALL_CMD

This doesn't work because bash interprets "GGML_CUDA=1" as a
command, not as an environment variable prefix.

Fix: Use conditional logic to run the commands directly:
  if GGML_CUDA=1 pip install ...; then
      GPU_INSTALL_SUCCESS=true
  fi
2026-02-12 10:10:06 -08:00
Jatin K MalikandGitHub 0241b0cb12 fix(install): install pywhispercpp with GPU support when available (#195)
The basic `pip install pywhispercpp` only includes CPU support.
For GPU acceleration, pywhispercpp must be installed with special
environment flags:
- NVIDIA GPU: GGML_CUDA=1 pip install git+...
- Vulkan (AMD/Intel): GGML_VULKAN=1 pip install git+...

This fix:
- Detects GPU type during whisper.cpp installation
- Installs pywhispercpp with appropriate GPU support flag
- Falls back to CPU version if GPU install fails

Fixes #193
2026-02-12 09:02:48 -08:00
Jatin K MalikandGitHub 04bb814a52 fix(ci): safely handle multi-line commit messages in deploy check (#194)
The previous implementation directly interpolated the commit message
into the shell script, which broke when messages contained newlines.
Words like "not" were being interpreted as shell commands.

Fix: Pass commit message via environment variable and write to temp file
before grepping, avoiding shell injection issues.
2026-02-12 08:44:27 -08:00
Jatin K MalikandGitHub 17bf62be64 fix(install): auto-install git if not present before cloning (#192)
Users running the install script via curl | bash may not have git
installed. This adds a check before attempting to clone the repo
and auto-installs git using the appropriate package manager for
the detected distribution.

Fixes issue reported on Reddit where install failed on Linux Mint
with "git command not found" error at line 170.
2026-02-12 08:34:40 -08:00
Jatin K MalikandGitHub 6a3c9fc6ec fix(web): properly handle speech recognition on both desktop and mobile browsers (#188)
The previous mobile fix broke desktop behavior by only taking the last result.
This fix uses resultIndex properly while also tracking processed results to
prevent duplication on mobile browsers where resultIndex stays at 0.

- Track processed results using a Set to avoid duplication
- Still use resultIndex for proper accumulation on desktop
- Clear processed results when starting a new session

Fixes speech result duplication issue on mobile while restoring
proper accumulation behavior on desktop browsers.
2026-02-12 01:34:33 -08:00
Jatin K MalikandGitHub 9e349f0b15 fix(web): prevent speech result duplication on mobile browsers (#187) 2026-02-12 01:09:30 -08:00
Jatin K MalikandGitHub 25aa0116cd fix(web): prevent speech result duplication on mobile browsers (#186) 2026-02-12 00:57:34 -08:00
Jatin K MalikandGitHub 03d55a989f chore(release): prepare v0.6.0-beta with whisper.cpp as default (#181)
* docs: update all documentation for whisper.cpp as default engine

Comprehensive documentation update highlighting whisper.cpp as the new
default speech recognition engine:

README.md:
- Added 'Major Change: whisper.cpp is Now Default!' section
- Updated Features to highlight whisper.cpp and Vulkan GPU support
- Updated Quick Install section with engine choices
- Changed default engine from whisper to whisper_cpp in examples
- Updated configuration examples
- Updated roadmap to mark whisper.cpp as complete

docs/INSTALL.md:
- Added whisper.cpp section with performance benefits
- Updated installation options (--engine flag)
- Added GPU support matrix and Vulkan detection info
- Added installation time comparison table
- Updated system requirements (lower disk space for whisper.cpp)

docs/USER_GUIDE.md:
- Added comprehensive 'Choosing Your Engine' section
- Added GPU acceleration information
- Updated tips to mention whisper.cpp benefits
- Added model size recommendations

web/src/app/page.tsx:
- Updated hero to mention whisper.cpp (C++ optimized, Vulkan support)
- Changed installation time from ~5-10 min to ~1-2 min
- Updated Features section to mention Vulkan GPU support
- Added whisper.cpp as default engine card (3-column layout)
- Updated installation commands (--engine flags)
- Updated FAQ about switching engines

This ensures all documentation reflects whisper.cpp as the new default
and highlights its major benefits: 10x faster install, universal GPU
support, and C++ optimized performance.

* chore(release): prepare v0.6.0-beta

This release brings whisper.cpp as the new default speech recognition engine:

Version Updates:
- Bump version from 0.5.0-beta to 0.6.0-beta
- Update src/vocalinux/version.py
- Update web/package.json

Documentation Updates:
- README.md: Update all v0.5.0-beta references to v0.6.0-beta
- docs/INSTALL.md: Update version references and installation commands
- docs/UPDATE.md: Add new 'What's New' section highlighting whisper.cpp
- SECURITY.md: Update supported versions table (0.6.x now supported)

Website Updates:
- web/src/app/layout.tsx: Update softwareVersion to 0.6.0-beta

Release Highlights:
- whisper.cpp is now the default engine (10x faster install!)
- Universal GPU support via Vulkan (AMD, Intel, NVIDIA)
- C++ optimized inference with multi-threading
- ~1-2 minute installation vs ~5-10 minutes before

Testing:
- All 472 tests passing
- Black formatting clean
- Flake8 linting clean
- isort import ordering clean

* ui(website): improve hero section layout

* docs(readme): remove duplicate What's New section
2026-02-11 20:33:28 -08:00
jatinkrmalik 051c84fd84 fix(ci): resolve merge conflict for nightly build renaming fix 2026-02-11 20:03:00 -08:00
jatinkrmalik 318e188245 fix(ci): handle both wheel and tar.gz file renaming in nightly builds
The sed pattern didn't correctly match tar.gz files which don't have
a dash after the version number. Fixed by explicitly handling both
.whl and .tar.gz file extensions with proper naming patterns.

Fixes the error: 'mv: source and destination are the same file'
2026-02-11 20:02:15 -08:00
Jatin K MalikandGitHub 4b51e9b8b0 fix(ci): improve nightly build workflow for user accessibility (#180)
The nightly build workflow was not creating accessible releases for users.
This fix addresses several issues:

- Add write permissions (contents: read → contents: write) to create GitHub releases
- Create a persistent 'nightly' pre-release that users can easily find and download
- Add workflow_dispatch trigger for manual testing
- Improve version naming: {base_version}.dev{date}+{short_sha}
- Extend artifact retention from 7 to 30 days
- Add clear installation instructions in release notes

Users can now access nightly builds at:
https://github.com/jatinkrmalik/vocalinux/releases/tag/nightly

Fixes #186
2026-02-11 19:52:22 -08:00
jatinkrmalik 61b8555356 fix(ci): improve nightly build workflow for user accessibility
The nightly build workflow was not creating accessible releases for users.
This fix addresses several issues:

- Add write permissions (contents: read → contents: write) to create GitHub releases
- Create a persistent 'nightly' pre-release that users can easily find and download
- Add workflow_dispatch trigger for manual testing
- Improve version naming: {base_version}.dev{date}+{short_sha}
- Extend artifact retention from 7 to 30 days
- Add clear installation instructions in release notes

Users can now access nightly builds at:
https://github.com/jatinkrmalik/vocalinux/releases/tag/nightly

Fixes #186
2026-02-11 19:48:46 -08:00
Jatin K MalikandGitHub 57a0ddd0b8 feat(speech): add whisper.cpp with Vulkan support for GPU acceleration (#179)
* feat(speech): add whisper.cpp with Vulkan support for GPU acceleration

Add whisper.cpp as a new speech recognition engine with the following features:
- Vulkan GPU acceleration support (AMD, Intel, NVIDIA)
- Fallback to CUDA for NVIDIA GPUs
- CPU-only mode with automatic thread optimization
- Support for all model sizes: tiny, base, small, medium, large
- Hardware detection to recommend best model/backend
- Models downloaded from Hugging Face (ggml format)
- Updated UI to show compute backend info in settings
- pywhispercpp as the Python binding library
- whisper_cpp as the new default engine

Changes:
- New whispercpp_model_info.py with model metadata and hardware detection
- Updated recognition_manager.py with whisper.cpp init and transcription
- Updated settings_dialog.py with whisper.cpp UI support
- Updated config_manager.py with whisper_cpp_model_size config
- Updated main.py with whisper_cpp CLI option
- Updated pyproject.toml with pywhispercpp dependency
- Updated install.sh with vulkan-tools for GPU detection

Closes #104

* style: fix black and isort formatting issues

* test: update config manager test for whisper_cpp default engine

* feat(install): interactive mode with 3 engine choices and whisper.cpp as default

Major changes to install.sh:
- Interactive mode is now the DEFAULT (not --auto)
- Added --auto flag for non-interactive automatic installation
- New --engine flag to specify engine directly
- Interactive mode shows 3 engine options with visual boxes:
  1. whisper.cpp (recommended) - Vulkan/CUDA/CPU support
  2. whisper (OpenAI) - PyTorch-based, NVIDIA-only
  3. VOSK - lightweight option
- Hardware detection with recommendations:
  - Detects Vulkan support (AMD/Intel/NVIDIA)
  - Detects NVIDIA CUDA
  - Checks available RAM
  - Recommends best engine based on hardware
- Updated help text with new options and examples
- Removed old --with-whisper, --whisper-cpu, --no-whisper flags
- whisper.cpp is now the default engine for automatic mode

* feat(uninstall): kill running vocalinux processes before uninstall

* fix(whisper.cpp): auto-download model, use all CPU cores, hide unavailable engines

Three fixes for whisper.cpp implementation:

1. Auto-download model during install
   - Added install_whispercpp_model() function to install.sh
   - Downloads ggml-tiny.bin (~39MB) from Hugging Face
   - Runs automatically when whisper.cpp engine is selected

2. Use all CPU cores for transcription
   - Added n_threads parameter to Model initialization
   - Uses multiprocessing.cpu_count() to get all cores
   - Significantly improves transcription speed

3. Hide unavailable engines from dropdown
   - Added get_available_engines() function to detect installed engines
   - Settings dialog now only shows engines that are actually installed
   - Falls back to first available engine if current not available

Fixes user-reported issues with whisper.cpp integration.

* ui(settings): display whisper.cpp correctly and increase dialog height

- Changed engine display name from 'whisper_cpp' to 'whisper.cpp'
- Added format_engine_display_name() helper function
- Dialog now uses 75% of screen height for better visibility
- More options visible by default without scrolling

* revert(settings): remove display name change, keep dialog height increase

- Reverted engine display name change (was breaking engine selection)
- Kept dialog height at 75% of screen for better visibility

* style: fix black and isort formatting for whisper.cpp logging

* style: fix black formatting in settings_dialog.py

* ci: fix Fedora 39 container package installation

Add dnf cache update and fallback with --nogpgcheck for Fedora containers
that may have stale or missing package metadata.
2026-02-11 19:37:58 -08:00
Jatin K MalikandGitHub 4a72c96b5f fix(text-injection): check ydotoold daemon before selecting ydotool (#176) 2026-02-11 17:26:21 -08:00
Jatin K MalikandGitHub 5e8336239f fix(install): add python3-dev dependency for evdev build (#177) 2026-02-11 17:19:51 -08:00
Jatin K MalikandGitHub ff994a3733 fix(install): prevent silent exit on systems without NVIDIA GPU (#175) 2026-02-11 17:12:46 -08:00
Jatin K MalikandGitHub e9134e0229 feat(web): show detected language with flag indicator in live demo (#169)
- Add language mapping with flag emojis for 40+ locales
- Display detected browser language in header with flag badge
- Show Listening in Language indicator when active
- Responsive design: language name hidden on mobile, flag always visible

Improves UX by making users aware of which language the speech recognition is configured for.
2026-02-09 23:46:42 -08:00
Jatin K MalikandGitHub 04eada775b feat: Phase 5 & 6 - Complete cross-distro compatibility fixes (#168)
Phase 5: Fix remaining hardcoded GI_TYPELIB_PATH values
- install.sh: Use dynamic GI_TYPELIB_DETECTED in package verification (line 1208)
- install.sh: Use dynamic path in desktop entry Exec line (line 1651)
- CI workflow: Use pkg-config for dynamic GI_TYPELIB_PATH detection (line 151)

Phase 6: Testing & validation improvements
- Add comprehensive test_cross_distro_compatibility.py test suite
- Tests verify no hardcoded paths, dynamic detection works, wrapper scripts correct
- Update DISTRO_COMPATIBILITY.md with implementation status and technical details

Fixes #157 (remaining issues)
Related to #48 (Snap packaging)
2026-02-09 21:07:25 -08:00
Jatin K MalikandGitHub 589d79dc92 fix(web): auto-detect browser language for live demo speech recognition (#166)
Use navigator.language instead of hardcoded 'en-US' so the demo works
for users with non-English browser settings (French, German, Spanish, etc.)

Fixes #165
2026-02-09 20:25:15 -08:00
Jatin K MalikandGitHub 8e48b997a5 ci: Actually test install.sh distro detection in CI matrix (#163)
* docs: Add distribution package mapping reference

Add a comprehensive YAML reference file documenting package names
across different Linux distributions. This serves as:

1. Documentation for manual installation on unsupported distros
2. Reference for adding support for new distributions
3. Auxiliary reference for the installer's embedded package mappings

Completes Task 6 from the cross-distribution compatibility fix plan.

Related to: #158, #159, #160, #161

* ci: Actually test install.sh distro detection in CI matrix

Previously, the distro-test-matrix.yml workflow only did syntax checks
on install.sh without actually testing the core cross-distribution
functionality that was added in phases 1-4.

This update adds proper tests for:

1. Distro Detection - Tests detect_distro() function logic across
   different containers to verify proper identification of Ubuntu,
   Debian, Fedora, etc.

2. Typelib Path Detection - Tests detect_typelib_path() function
   which uses pkg-config and fallback paths for GI_TYPELIB_PATH

3. Virtual Environment Creation - Verifies Python venv can be
   created with minimal system dependencies

4. Dependency Checker - Runs check-system-deps.sh to see what's
   missing on each distro

5. Installer Help - Verifies install.sh --help works

This ensures the cross-distribution compatibility improvements
are actually tested by CI, not just syntax-checked.

Related to: #158, #159, #160, #161, #162

* ci: Fix distro test - avoid sourcing install.sh (root check fails)

The install.sh script has a root check that exits immediately when
running as root, which causes CI to fail when we try to source it.

Instead, we now test the distro detection logic directly without
sourcing install.sh. This gives us the same test coverage while
avoiding the root check issue.
2026-02-07 18:22:02 -08:00
Jatin K MalikandGitHub 9efe53e088 docs: Add distribution package mapping reference (#162)
Add a comprehensive YAML reference file documenting package names
across different Linux distributions. This serves as:

1. Documentation for manual installation on unsupported distros
2. Reference for adding support for new distributions
3. Auxiliary reference for the installer's embedded package mappings

Completes Task 6 from the cross-distribution compatibility fix plan.

Related to: #158, #159, #160, #161
2026-02-07 17:07:59 -08:00
Jatin K MalikandGitHub 6b0e81c117 feat: Phase 4 - Testing & Polish improvements (#161)
Add testing infrastructure and documentation improvements.

**Task 12: Add pkg-config to Core Dependencies**
- Added pkg-config check at the start of install_system_dependencies()
- Added pkg-config to all distribution package lists
- Provides distro-specific install instructions if pkg-config is missing
- Critical for library detection (GI_TYPELIB_PATH, PortAudio, etc.)

**Task 13: Update README with Distro Info**
- Updated Requirements section with tested distributions
- Added link to DISTRO_COMPATIBILITY.md
- Listed officially supported distros: Ubuntu 22.04+, Debian 11+, Fedora 39+, Arch, openSUSE
- Mentioned experimental support for Gentoo, Alpine, Void, Solus

**Task 14: Create Test Matrix for CI**
- New workflow: .github/workflows/distro-test-matrix.yml
- Tests on multiple container images: Ubuntu 22.04, 24.04, Debian 12, Fedora 39
- Runs dependency checker on each distro
- Tests Python imports and bash syntax validation
- Uses continue-on-error for experimental distro support

**Task 15: Integration Testing Checklist**
- New file: tests/distro-testing-checklist.md
- Comprehensive checklist for testing on new distributions
- Covers: Pre-install, Installation, Post-install, Functionality, Performance, Cleanup
- Includes quick reference commands
- Desktop environment and application-specific testing sections
- Template for submitting test results

Part of cross-distribution compatibility improvements (Phase 4 of 5).
Related to #157
2026-02-07 16:59:29 -08:00
Jatin K MalikandGitHub 461400b3bc feat: Phase 3 - Better error handling and documentation (#160)
Add better error messages and documentation for cross-distribution compatibility.

**Task 9: System Dependency Checker (scripts/check-system-deps.sh)**
- New script to check system dependencies regardless of distribution
- Detects Python 3.8+, pkg-config, GTK3, PyGObject, PortAudio
- Checks for text injection tools (xdotool, wtype, ydotool)
- Provides distribution-specific installation instructions
- Supports all 10+ distribution families (Ubuntu, Debian, Fedora, Arch, openSUSE, Gentoo, Alpine, Void, Solus, Mageia)

**Task 10: Better Unsupported Distro Message (install.sh)**
- Enhanced error message for unsupported distributions
- References the new dependency checker script
- Provides manual installation options (skip-system-deps, venv install)
- Includes link to project wiki
- Interactive prompt to continue or cancel

**Task 11: Distro Compatibility Documentation (docs/DISTRO_COMPATIBILITY.md)**
- Comprehensive compatibility matrix for supported distros
- Experimental support section with known issues
- Requirements by distribution with exact commands
- Desktop environment compatibility (GNOME, KDE, Xfce, sway, i3, etc.)
- Display server support (X11, Wayland, XWayland)
- Architecture support (x86_64, arm64, armhf, riscv64)
- Testing checklist for new distributions
- Issue reporting guidelines
- Contributing guidelines for compatibility fixes

Part of cross-distribution compatibility improvements (Phase 3 of 5).
Related to #157
2026-02-07 16:50:50 -08:00
Jatin K MalikandGitHub f2e13bbcba feat: Phase 2 - Enhanced distro detection and package manager support (#159)
Add support for 5 additional Linux distribution families:

**New Distribution Detection:**
- Gentoo (Portage package manager)
- Alpine Linux (apk package manager)
- Void Linux (xbps package manager)
- Solus (eopkg package manager)
- Mageia (dnf/urpmi package managers)

**Changes:**
- Enhanced `detect_distro()` to detect Gentoo, Alpine, Void, Solus, Mageia
- Added package definitions for each new distribution in `install_system_dependencies()`
- Added full installation case statements with package verification
- Updated `install_python_dependencies()` to handle virtual environment creation for new distros
- Updated `install_text_input_tools()` for both Wayland and X11 sessions
- Updated unknown session type fallback with all new distributions

**Package Manager Support:**
- emerge: Gentoo's Portage (compiles from source)
- apk: Alpine's package manager (musl libc)
- xbps: Void Linux's package manager
- eopkg: Solus's package manager
- dnf/urpmi: Mageia's package managers

Part of cross-distribution compatibility improvements (Phase 2 of 5).
Related to #157
2026-02-07 16:35:40 -08:00
Jatin K MalikandGitHub 2b498f0888 fix: Phase 1 - Critical cross-distribution compatibility fixes (#158)
* fix: Phase 1 - Critical cross-distribution compatibility fixes

This commit implements the first phase of cross-distribution compatibility
improvements for Vocalinux, addressing the most critical issues that prevent
the application from working on non-Ubuntu distributions.

## Changes

### install.sh
- Add detect_typelib_path() function that dynamically discovers GI_TYPELIB_PATH
  using pkg-config with fallback to distribution-specific paths
- Update wrapper scripts (vocalinux, vocalinux-gui) to use detected path
- Support for: x86_64, arm64, armhf, riscv64, powerpc64le, s390x architectures
- Specific paths for: Ubuntu multiarch, Fedora/RHEL (lib64), Arch (lib)

### src/vocalinux/speech_recognition/recognition_manager.py
- Add _get_system_model_paths() function for dynamic model path discovery
- Enhance ALSA library detection with multiple library name fallbacks:
  - libasound.so.2, libasound.so, libasound.so.0, asound
- Support XDG_DATA_DIRS environment variable for model paths
- Distribution-specific paths for Fedora/RHEL/CentOS/Rocky/AlmaLinux
- Arch-specific handling (excludes /usr/local)

### src/vocalinux/utils/resource_manager.py
- Enhanced _find_resources_dir() with more candidate paths
- Support for XDG_DATA_DIRS environment variable
- Add lib64 and lib paths for Fedora/RHEL distributions
- Add Flatpak-specific path (/app/share/vocalinux/resources)

## Testing

All 462 existing tests pass.

## Related Issues

Fixes #157 (partial - Phase 1 of 5)

* chore: Remove analysis docs from PR, add to .gitignore

* style: Apply black formatting to pass lint checks
2026-02-07 16:26:49 -08:00
Jatin K MalikandGitHub 3bd9f8e1db Update README.md 2026-02-06 00:45:06 -08:00
Jatin K MalikandGitHub 04aa999dba fix(web): make quick install command fully visible by enabling text wrap (#156) 2026-02-05 20:34:03 -08:00
Jatin K MalikandGitHub 257749f11a fix(website): update install commands to use /tmp/vl.sh for better UX (#154)
* feat(readme): add screenshots section to README

* feat(readme): add transcription screenshot to README

* feat(readme): remove duplicate settings screenshot, keep annotated version

* refactor(readme): move screenshots to resources directory

* feat(resources): add screenshots directory

* feat(readme): add all screenshots in 2x2 table layout with full-width features overview

* docs(readme): mark Improved Wayland support as completed in roadmap

* feat(website): update install commands to use /tmp/vl.sh for better UX
2026-02-05 20:10:29 -08:00
Jatin K MalikandGitHub 03caf4734f feat(readme): add screenshots section to README (#153)
* feat(readme): add screenshots section to README

* feat(readme): add transcription screenshot to README

* feat(readme): remove duplicate settings screenshot, keep annotated version

* refactor(readme): move screenshots to resources directory

* feat(resources): add screenshots directory

* feat(readme): add all screenshots in 2x2 table layout with full-width features overview

* docs(readme): mark Improved Wayland support as completed in roadmap
2026-02-05 19:54:10 -08:00
jatinkrmalik fc446254ac fix(readme): restore installation section and fix new section positioning
Accidentally removed entire 'Alternative: Install from Source' section
when adding 'What's New' content. Restored the original section
with installation commands and After Installation instructions.

Moved 'What's New in v0.5.0-beta' section to be positioned
correctly (before the 'Beta Release' announcement, not after 'Requirements').

All install commands now correctly reference v0.5.0-beta.
2026-02-05 19:11:00 -08:00
jatinkrmalik 96867310be docs(readme): add beta release announcement and changelog summary
- Update announcement from Alpha to Beta release
- Add What's New section highlighting key improvements in v0.5.0-beta
- Mention critical bug fixes (text escaping, stop sound, spacing)
- Mention key new features (custom shortcuts, GNOME HIG UI, pleasant tones, GPU detection)
- Mention quality improvements (80%+ test coverage, microphone reconnection)
- Remove CHANGELOG.md reference (using release notes instead)
- Update status badge from Alpha to Beta

This prepares the repository for v0.5.0-beta release notes.
2026-02-05 19:07:31 -08:00
Jatin K MalikandGitHub d004a401af chore(release): prepare v0.5.0-beta (#148)
This commit prepares the repository for the v0.5.0-beta release,
transitioning from alpha to beta status.

Changes made:
- Update version from 0.4.1-alpha to 0.5.0-beta in version.py
- Update Development Status classifier from Alpha to Beta in pyproject.toml and setup.py
- Update status badges from Alpha (orange) to Beta (blue) in README.md
- Update all installation command examples to use v0.5.0-beta tag
- Update release announcement from Alpha to Beta in README.md
- Add RELEASE_PROCESS.md documentation for future releases
- Update docs/INSTALL.md with new version references
- Add What's New section for v0.5.0-beta in docs/UPDATE.md
- Update SECURITY.md supported versions table
- Update website schema softwareVersion in layout.tsx
- Update website version badges in page.tsx
- Update website package.json version to 0.5.0

Testing:
- All 463 tests passing (100%)
- Version consistency verified across all files

Release process documentation added to docs/RELEASE_PROCESS.md
2026-02-05 19:00:17 -08:00
Jatin K MalikandGitHub 099f9d27ad fix(ci): make workflow robust to special characters in commit messages (#152)
The unified-pipeline workflow was failing when commit messages contained
special characters (like quotes in 'won\'t be transcribed'). The shell
pattern matching was fragile and would break on various characters.

Fix:
- Replace fragile glob pattern matching with grep case-insensitive search
- Look for common website-related commit prefixes:
  feat(website)
  docs(website)
  chore(website)
  fix(website)
  refactor(website)
- This is more robust and handles special characters gracefully
- Fix YAML formatting issue with blank line

This makes the CI workflow more reliable and less fragile.
2026-02-05 18:56:51 -08:00
Jatin K MalikandGitHub fdf1de5180 fix(transcription): add space after punctuation when transcribing again (#151)
When transcribing text continuously (stop and start again), the new
text was being injected immediately after the last character without a
space. This caused issues like "Hello world.This is a test" instead of
"Hello world. This is a test".

Fix:
- Check if the last injected text ends with punctuation or other characters
  that typically need a space after them (., ,, !, ?, ;, :, quotes, etc.)
- If yes, add a space before injecting the new text
- Log when space is added for debugging

Characters requiring space:
- Punctuation: . , ! ? ; : ) ] } - _
- Quotes: " '

Closes #151
2026-02-05 18:47:38 -08:00
Jatin K MalikandGitHub 81d1973b7d fix(recognition): prevent stop sound from being transcribed (#150)
When stopping voice recognition, the stop sound was being captured by the
microphone and transcribed as "thank you" or similar text. This happened
because the sound was played BEFORE stopping recording.

Fix:
- Stop recording FIRST by setting should_record = False
- Wait briefly for audio thread to stop
- Discard the last ~1 second of audio buffer (15 chunks) which would
  contain the feedback sound
- THEN play the stop sound after recording has stopped
- Process remaining valid audio

This ensures that audio captured during the stop sound is discarded and
won't be transcribed.

Technical details:
- Audio recorded in 1024-sample chunks at 16000 Hz = ~64ms per chunk
- Discarding 15 chunks = ~960ms of audio
- Uses existing _buffer_lock for thread safety

Closes #150
2026-02-05 18:31:14 -08:00
Jatin K MalikandGitHub 1593e9f962 fix(text-injection): remove unnecessary shell escaping for subprocess calls (#149)
Removes the _escape_text method and its usage since text is passed to
subprocess.run() via list arguments, not shell strings. When using
subprocess with a list (without shell=True), arguments are passed directly
to the command without shell interpretation, making shell escaping
unnecessary and actually harmful.

This fixes the bug where apostrophes and other special characters were
typed with backslash escapes (e.g., "Let\'s" instead of "Let's").

Changes:
- Remove _escape_text() method from TextInjector class
- Remove escaped_text variable from inject_text() method
- Pass text directly to _inject_with_xdotool() and _inject_with_wayland_tool()
- Update docstrings to remove references to escaped text
- Update tests to verify text is NOT escaped when passed to subprocess

Closes #119
2026-02-05 18:21:14 -08:00
Jatin K MalikandGitHub 3add0fd23e feat(website): make interactive install the default and remove voice commands section (#146)
* feat(website): make interactive install the default

- Updated hero section Quick Install to use interactive mode
- Changed label to 'Quick Install (Interactive)' with guided installation description
- Removed duplicate Interactive Install section from detailed install area
- Renamed 'Quick Install (Auto-detect)' to 'Auto-detect Install' as alternative option

* feat(website): remove voice commands section

- Removed 'Built-in Voice Commands' section from website
- Removed navigation and footer links to voice commands
- Voice commands functionality remains in app but not featured on website

Voice commands implementation is being reconsidered for future releases as
Whisper models now handle punctuation well natively.
2026-02-05 17:57:39 -08:00
Jatin K MalikandGitHub a5b933a546 feat(audio): replace sound alerts with more pleasant tones (#145)
Replace the current jarring sound alerts with smoother, more pleasant
bell-like tones inspired by voice assistants like Siri and Gemini.

Changes:
- start_recording.wav: Ascending perfect fifth (A4→E5, 0.30s)
- stop_recording.wav: Descending perfect fifth (E5→A4, 0.25s)
- error.wav: Low gentle chime (E4, 0.35s)

Technical improvements:
- Smooth frequency sweeps (sigmoid curve transitions)
- Subtle vibrato (8Hz) for warmth and richness
- Harmonic overtones for fullness
- Elegant exponential decay envelopes
- Reduced file sizes (926KB → 80KB total)

The new sounds are shorter (0.25-0.35s vs 0.5-1s), quieter
(20-25% amplitude vs full volume), and more pleasant for frequent use.
2026-02-05 17:48:05 -08:00
Jatin K MalikandGitHub 1e97f36d6c fix(ui): prevent scroll events from modifying settings widgets on hover (#143)
Add _prevent_scroll_on_hover() helper function that blocks scroll events
on ComboBoxes and SpinButtons unless they have explicit focus. This fixes
the UX issue where scrolling through the settings dialog accidentally
changes dropdown/spinbutton values when the mouse cursor happens to be
over them.

Changes apply to:
- Audio device combo
- Engine selection combo
- Model size combo
- Language selection combo
- VAD sensitivity spin button
- Silence timeout spin button
- Keyboard shortcut combo

Users must now click/focus a widget first before scroll events will
modify its value, making scrolling through settings much more predictable.
2026-02-05 17:08:34 -08:00
Jatin K MalikandGitHub ab47329706 fix(website): critical SEO fixes - schema version, FAQ & HowTo structured data (#142)
* fix(website): update schema version and add structured data for SEO

- Fix softwareVersion from "0.0.0" to "0.4.1-alpha" in SoftwareApplication schema
- Add FAQPage schema for rich results in search engines
- Add HowTo schema for installation guide steps
- Update sitemap.xml lastmod date to 2026-02-05

Fixes #138

* ci: skip Python builds when only web/ folder changes

- Add path filters to detect changes in web/ vs Python files
- Make python-lint and python-test jobs depend on changes job
- Skip Python CI when only web files are modified
- Expand Python path filters to include common config files

Closes #138
2026-02-05 17:01:19 -08:00
Jatin K MalikandGitHub 7a1c42aae6 feat(shortcuts): add customizable keyboard shortcuts via GUI (#137)
* feat(shortcuts): add customizable keyboard shortcuts via GUI

Implement configurable keyboard shortcuts for toggling voice recognition,
allowing users to choose between Ctrl+Ctrl, Alt+Alt, Shift+Shift, or
Super+Super (Windows key) double-tap shortcuts.

Changes:
- Add shortcuts configuration section to settings dialog with dropdown
- Update keyboard backends (pynput and evdev) to support configurable
  modifier keys for double-tap detection
- Add SUPPORTED_SHORTCUTS, SHORTCUT_DISPLAY_NAMES constants in base module
- Update KeyboardShortcutManager to accept and pass shortcut configuration
- TrayIndicator now reads shortcut from config on startup
- Add comprehensive tests for shortcut configuration and parsing

The default shortcut remains Ctrl+Ctrl for backward compatibility.
Changes take effect after app restart (noted in UI).

Closes #16

* feat(shortcuts): enable live shortcut switching without app restart

Add restart_with_shortcut() method to KeyboardShortcutManager that stops
the listener, updates the shortcut configuration, and restarts with the
new shortcut. The settings dialog now applies shortcut changes immediately
with visual feedback indicating success.

- Add restart_with_shortcut() to KeyboardShortcutManager
- Add update_shortcut() to TrayIndicator for exposing live updates
- Update SettingsDialog to use callback for immediate shortcut changes
- Show green success message when live switching succeeds
- Add 7 new tests for restart_with_shortcut functionality

* fix: use Python 3.8 compatible context manager syntax

Convert parenthesized context manager (Python 3.10+) to nested with
statements for Python 3.8 compatibility in test_keyboard_shortcuts.py
2026-02-05 16:47:29 -08:00
Jatin K MalikandGitHub c75893b2a4 test: add comprehensive tests for UI dialog redesigns (#135)
* test: add comprehensive tests for UI dialog redesigns

- Add tests for AboutDialog (show_about_dialog function and class)
- Add tests for LoggingDialog (CSS, filtering, actions, toast notifications)
- Update SettingsDialog tests for instant-apply pattern (Close-only buttons)
- Use source code inspection to verify method existence with GTK mocks
- All 382 tests passing

* fix(test): rewrite UI dialog tests to use source inspection

Replace GTK mocking with source code inspection approach to fix
CI failures on Python 3.8 and 3.10. The new approach reads source
files directly and verifies method definitions, CSS classes, and
expected code patterns exist, avoiding Python version-specific
module caching issues with patched imports.
2026-02-05 14:51:36 -08:00
Jatin K MalikandGitHub 192b089c97 feat(ui): redesign settings dialog with modern GNOME HIG styling (#133)
* feat(ui): redesign settings dialog with modern GNOME HIG styling

Completely redesign the settings dialog to follow GNOME Human Interface
Guidelines with a modern, card-based preference page layout:

UI/UX Improvements:
- Add PreferencesGroup and PreferenceRow custom widgets mimicking
  libadwaita's AdwPreferencesPage pattern
- Implement proper visual hierarchy with card-style grouped sections
- Add comprehensive CSS stylesheet with theme-aware colors
- Use proper spacing, border-radius, and typography following HIG
- Add smooth reveal animations for settings applied notifications
- Improve status indicators with semantic colors (success/warning/error)

Technical Changes:
- Replace flat grid layout with scrollable content area
- Use ListBox rows for better accessibility and keyboard navigation
- Add proper Gdk version requirement to prevent version conflicts
- Consolidate model info display into a unified info card
- Improve code organization with dedicated section builder methods

Visual Features:
- Card-like preference groups with subtle borders and shadows
- Proper row hover states for interactive feedback
- Status color coding: green for success, yellow for warnings, red for errors
- Cleaner legend display for model download status
- Modern flat button styling for auxiliary actions

All 328 existing tests continue to pass.

* refactor(settings): simplify to Close-only button pattern

Remove Apply/Cancel buttons in favor of pure instant-apply UX:
- Settings now apply immediately when changed (auto-apply)
- Single Close button follows modern GNOME Settings pattern
- Remove redundant _revert_settings() and _show_settings_applied_message()
- Update docstring to reflect instant-apply design

This resolves the UX inconsistency where settings auto-applied
but also had Apply/Cancel buttons that were confusing.

* feat(ui): redesign Logs and About dialogs with GNOME HIG styling

Logs Dialog:
- Modern card-based filter bar with grouped controls
- Theme-aware log level colors (works in light/dark mode)
- Toolbar with icon buttons for Copy, Export, Clear actions
- Toast notifications for user feedback
- Close-only button pattern (consistent with settings)

About Dialog:
- Extract to separate about_dialog.py module
- Use standard Gtk.AboutDialog (GNOME recommended)
- Clean credits section with contributors and tech stack
- Remove emojis for cleaner professional look
- Better organized credit sections

Both dialogs now follow the same design language as the
Settings dialog redesign.
2026-02-05 14:32:43 -08:00
Jatin K MalikandGitHub 2becfb5a98 fix(install): fix model download and VOSK-only option in interactive mode (#132)
* fix(install): fix model download and VOSK-only option in interactive mode

- Add missing option 3 handling in interactive prompt to create VOSK
  config when user selects VOSK-only mode (mirrors --no-whisper flag)
- Set WITH_WHISPER and WHISPER_CPU flags correctly for options 1 and 2
- Fix Whisper model download logic to check actual installation status
  using venv python instead of relying on unreliable flag combinations
- Always download Whisper tiny model when Whisper is installed since
  it's the default engine in config_manager.py
- Add informative messages about model download status

Fixes issues where:
1. Selecting option 2 or 3 didn't properly configure the system
2. Whisper tiny model wasn't downloaded even when Whisper was selected
3. App defaulted to Whisper engine but model wasn't available

* fix(install): use explicit venv python path and simplify condition

- Use $VENV_DIR/bin/python instead of bare 'python' in run_tests() and
  verify_installation() for consistency and reliability
- Simplify Whisper install condition since WITH_WHISPER is already set
  by auto-detection in non-interactive mode (lines 412-424)
- Update comments to better explain the logic flow

* style(install): restore ASCII art logo and improve formatting

- Restore beautiful VOCALINUX ASCII art banner in interactive installer
- Restore ASCII art banner in installation complete message
- Use Unicode box-drawing characters (━) for section separators
- Use bullet points (•) instead of dashes for lists
- Add colored terminal output for commands
- Add star emoji for GitHub link

* style(install): show ASCII art banner in all installation modes

The ASCII art logo is now displayed at the start of installation
regardless of mode (interactive, curl|bash, or with flags).

* fix(install): remove duplicate ASCII art in interactive mode

The ASCII art banner is now shown once at script start for all modes.
Remove the duplicate from run_interactive_install() to avoid showing
it twice when running with -i/--interactive flag.

* docs(install): rename options to 'Full install' and 'Minimal install'

Clarify that VOSK is always installed as a fallback engine:
- 'Full install' = Whisper + VOSK (recommended, highest accuracy)
- 'Minimal install' = VOSK only (lightweight, ~40MB)

Updates both the -i interactive installer and the fallback prompt.
Also improves the installation summary display.

* fix(install): update desktop database so app appears in menu immediately

Previously only the icon cache was updated after installation, but not
the desktop database. This caused the app to not appear in application
menus until the user logged out and back in (or manually ran
update-desktop-database).

Now the installer runs update-desktop-database after installing the
.desktop file, so Vocalinux appears in the app launcher immediately.
2026-02-05 13:45:26 -08:00
Jatin K MalikandGitHub b62fb9049b feat(ci): add nightly build workflow (#129)
- Adds scheduled daily builds at 2 AM UTC
- Builds Python packages and uploads as artifacts
- 7-day retention to keep storage minimal
- No release tab pollution - artifacts only
2026-02-05 01:06:51 -08:00