* feat: prepare for v0.2.0-alpha release * feat: prepare for v0.2.0-alpha release * chore: remove CHANGELOG.md, use GitHub Releases instead * refactor: use existing About dialog instead of Settings section * style: enhance About dialog UI readability * style: fix formatting with black and isort * feat: show VAD and silence timeout settings for Whisper engine - Renamed 'VOSK Settings' to 'Recognition Settings' - VAD Sensitivity and Silence Timeout now apply to both engines - Added tooltips explaining each setting - VOSK-specific model info only shown when VOSK selected * fix: resolve overlapping UI elements in settings dialog * fix: save VAD and silence timeout settings for both engines Previously these settings were only saved when VOSK was selected. Now they persist correctly for Whisper as well. * fix: show download progress when selecting undownloaded model Previously when auto-applying settings, models would download silently in the background without showing the progress dialog. Now: - Download progress dialog appears for undownloaded models - Model icons update correctly after download completes * feat: add download progress, speed, ETA and cancel button - Show real download progress percentage for VOSK models - Display download speed (MB/s) and estimated time remaining - Add Cancel button to abort downloads - Update status during extraction phase - Whisper downloads still pulse (uses internal downloader) * fix: defer model download until needed, don't block startup - App now starts instantly even if models aren't downloaded - Models are downloaded on-demand when selected in Settings - If user tries to dictate without a model, plays error sound - Added model_ready property to check if engine is usable * fix: improve first-run UX without downloaded models - Settings dialog now defaults to smallest available model, not saved config - Only show saved model if it's actually downloaded - Add desktop notification when trying to dictate without a model - Prevents auto-downloading large models on first launch * feat: add download progress tracking for Whisper models - Implement custom Whisper model download with progress/speed/ETA - Uses OpenAI's CDN URLs directly instead of whisper.load_model() - Progress callback works the same as VOSK downloads - Supports cancellation during download * fix: enable download progress callback for Whisper models Progress callback was only being set for VOSK downloads, not Whisper. Now both engines show real-time progress, speed, and ETA. * fix: update tests for defer_download and config manager mocking - test_main: Mock ConfigManager to prevent saved config from overriding test values - test_settings_dialog: Mock ModelDownloadDialog to prevent GTK init errors - test_speech_recognition: Use proper MockVoskModule class instead of MagicMock, pass defer_download=False for download test - test_whisper_support: Pass defer_download=False to trigger model loading in test * fix: resolve test failures for CI - test_main: Fix ConfigManager patch path to use source module - test_settings_dialog: Mock _is_vosk_model_downloaded and _is_whisper_model_downloaded to skip download flow, add missing dialog attributes - test_speech_recognition: Replace recognizer with properly configured mock that returns valid JSON, fixing test isolation issues when running all tests together * fix: mock _download_whisper_model in whisper test to avoid requests exception handling issue * fix: add gir1.2-girepository-2.0 dep for PyGObject on Ubuntu 24.04 - Add missing girepository-2.0 package for newer Ubuntu runners - Use --no-build-isolation for PyGObject to use system packages * fix: skip PyGObject pip install, use system python3-gi package - Use --no-deps for editable install to skip PyGObject - Install other deps explicitly without PyGObject - Add python3-gi-cairo for complete GTK support - Removes problematic girepository-2.0 build requirement * fix: install PyGObject via pip with proper build deps - Remove python3-gi/python3-gi-cairo (doesn't work with setup-python) - Install PyGObject from pip after installing build dependencies - Simplify venv setup without --system-site-packages hack * Fix GObject * fix: set GI_TYPELIB_PATH for pip-installed PyGObject to find AppIndicator3
7.5 KiB
Contributing to Vocalinux
Thank you for your interest in contributing to Vocalinux! 🎉
This document provides guidelines and instructions for contributing to the project.
📋 Table of Contents
- Code of Conduct
- Getting Started
- Development Setup
- Making Changes
- Testing
- Pull Request Process
- Release Process
- Community
Code of Conduct
We are committed to providing a welcoming and inclusive environment. Please be respectful and constructive in your interactions.
Getting Started
Ways to Contribute
- 🐛 Report bugs - Found a bug? Open an issue
- 💡 Suggest features - Have an idea? Start a discussion
- 📖 Improve documentation - Docs can always be better!
- 🔧 Fix bugs - Check the issues for things to work on
- ✨ Add features - Pick up a feature from the roadmap
Good First Issues
New to the project? Look for issues labeled good first issue.
Development Setup
Option 1: Automated Setup (Recommended)
# Fork and clone the repository
git clone https://github.com/YOUR-USERNAME/vocalinux.git
cd vocalinux
# Install in development mode (includes all dev dependencies)
./install.sh --dev
This will:
- Install all system dependencies
- Create a Python virtual environment
- Install the package in editable mode (
-e) - Install all dev dependencies (pytest, black, isort, flake8)
- Run the test suite automatically
Option 2: Manual Setup
-
Fork and clone:
git clone https://github.com/YOUR-USERNAME/vocalinux.git cd vocalinux -
Install system dependencies:
# Ubuntu/Debian sudo apt update sudo apt install -y python3-pip python3-gi python3-gi-cairo \ gir1.2-gtk-3.0 gir1.2-appindicator3-0.1 libgirepository1.0-dev \ python3-dev portaudio19-dev python3-venv xdotool -
Set up Python environment:
python3 -m venv venv --system-site-packages source venv/bin/activate pip install --upgrade pip setuptools wheel pip install -e ".[dev]" -
(Optional) Install pre-commit hooks:
pre-commit installNote: Pre-commit hooks are optional. The CI pipeline runs the same checks, so you can skip this if you prefer faster local commits.
Making Changes
Branching Strategy
# Create a feature branch from main
git checkout main
git pull origin main
git checkout -b feature/your-feature-name
# Or for bug fixes
git checkout -b fix/issue-description
Branch naming conventions:
feature/- New featuresfix/- Bug fixesdocs/- Documentation updatesrefactor/- Code refactoringtest/- Test additions/updates
Code Style
We use automated tools to ensure consistent code style:
- Black - Code formatting (line length: 100)
- isort - Import sorting (black-compatible profile)
- flake8 - Linting
# Format your code
black src/ tests/
isort src/ tests/
# Check for issues
flake8 src/ tests/
Pre-commit hooks will run these automatically before each commit.
Project Structure
vocalinux/
├── src/vocalinux/ # Main application code
│ ├── __init__.py
│ ├── main.py # Entry point
│ ├── version.py # Version information
│ ├── common_types.py # Shared types/enums
│ ├── speech_recognition/ # Speech recognition engines
│ │ ├── recognition_manager.py
│ │ └── command_processor.py
│ ├── text_injection/ # Text injection (X11/Wayland)
│ │ └── text_injector.py
│ ├── ui/ # GTK UI components
│ │ ├── tray_indicator.py
│ │ ├── settings_dialog.py
│ │ ├── config_manager.py
│ │ └── ...
│ └── utils/ # Utility functions
├── tests/ # Test suite
├── resources/ # Icons and sounds
├── docs/ # Documentation
└── web/ # Website source (Next.js)
Key Files for Common Tasks
| Task | Files |
|---|---|
| Add voice command | src/vocalinux/speech_recognition/command_processor.py |
| UI changes | src/vocalinux/ui/*.py |
| Speech recognition | src/vocalinux/speech_recognition/recognition_manager.py |
| Text injection | src/vocalinux/text_injection/text_injector.py |
| Settings | src/vocalinux/ui/config_manager.py, settings_dialog.py |
Testing
Running Tests
# Activate virtual environment
source venv/bin/activate
# Run all tests
pytest
# Run with coverage
pytest --cov=src --cov-report=html
# Run specific test file
pytest tests/test_command_processor.py
# Run with verbose output
pytest -v
Writing Tests
- Place tests in the
tests/directory - Name test files as
test_*.py - Name test functions as
test_* - Aim for at least 80% coverage for new code
- Use
pytest-mockfor mocking
Example test:
def test_command_processor_new_line(mocker):
"""Test that 'new line' command returns correct action."""
processor = CommandProcessor()
result = processor.process("new line")
assert result.action == "new_line"
Pull Request Process
Before Submitting
- Code follows the style guidelines
- Tests pass locally (
pytest) - Pre-commit hooks pass
- Documentation is updated (if needed)
- Commit messages are clear and descriptive
Commit Messages
Follow the Conventional Commits style:
type(scope): short description
Longer description if needed.
Fixes #123
Types: feat, fix, docs, style, refactor, test, chore
Examples:
feat(commands): add "select all" voice command
fix(tray): resolve icon not updating on Wayland
docs(readme): update installation instructions
Submitting
- Push your branch to your fork
- Open a Pull Request against
main - Fill out the PR template
- Link any related issues
- Wait for CI to pass
- Request a review
Review Process
- PRs require at least one approval
- CI must pass (linting, tests)
- Maintainers may request changes
- Once approved, maintainers will merge
Release Process
Releases are managed through GitHub tags and the release workflow.
Version Bumping
- Update version in
src/vocalinux/version.py - Commit:
git commit -m "chore: bump version to x.y.z" - Tag:
git tag vx.y.z - Push:
git push origin main --tags - GitHub Release will be auto-created with release notes
Versioning Scheme
We follow Semantic Versioning:
- MAJOR.MINOR.PATCH (e.g.,
1.2.3) - Pre-release:
x.y.z-alpha,x.y.z-beta,x.y.z-rc.1
Community
Getting Help
- 💬 GitHub Discussions - Ask questions
- 🐛 GitHub Issues - Report bugs
Stay Connected
- ⭐ Star the repository to show support
- 👀 Watch for updates
- 🐦 Follow @jatinkrmalik on Twitter
Thank you for contributing to Vocalinux! ❤️