Files
voculinux/CONTRIBUTING.md
xavierk 4171567fd7
CI / security (push) Successful in 1m12s
CI / lint (push) Successful in 21s
CI / ai-review (push) Skipped
docs: publish Void xbps as the only install channel, drop upstream references (#38)
User-facing docs, About page and website now point at the fork and the Void xbps repository, with one credit line to upstream Vocalinux. Channels this fork does not publish are removed from navigation.
2026-11-06 16:17:04 +00:00

9.1 KiB

Contributing to Voculinux

Thanks for your interest in contributing. This guide covers setup, style, testing, and pull requests.

Code of conduct

Participation is covered by our Code of Conduct. Be respectful and constructive.

Ways to contribute

  • Report bugs - Open an issue
  • Suggest features - Open an issue with the capability you want
  • Improve documentation - Fixes and clarity are always useful
  • Fix bugs or add features - Check open issues

Development setup

git clone https://git.bongbetic.com/YOUR-USERNAME/voculinux.git
cd voculinux
./install.sh --dev

This installs system dependencies, creates venv/ with an editable install and dev tools, and runs the test suite. See The two environments.

Manual setup

  1. Fork and clone the repository.

  2. Install system dependencies (examples). Voculinux is published only as a Void Linux xbps package; the distro examples below are for building from a source checkout:

    Ubuntu 24.04+:

    sudo apt update
    sudo apt install -y python3-pip python3-gi python3-gi-cairo \
         gir1.2-gtk-3.0 gir1.2-ibus-1.0 libgirepository-2.0-dev libgirepository1.0-dev \
         build-essential pkg-config libcairo2-dev libffi-dev \
        python3-dev portaudio19-dev python3-venv xdotool
    

    Debian 12 (installer environment only):

    sudo apt install -y python3-pip python3-gi python3-gi-cairo \
         gir1.2-gtk-3.0 gir1.2-ibus-1.0 libgirepository1.0-dev libcairo2-dev \
         build-essential pkg-config libffi-dev \
        python3-dev portaudio19-dev python3-venv xdotool
    

    Debian 13+:

    sudo apt install -y python3-pip python3-gi python3-gi-cairo \
         gir1.2-gtk-3.0 gir1.2-ibus-1.0 libgirepository-2.0-dev libcairo2-dev \
         build-essential pkg-config libffi-dev \
        python3-dev portaudio19-dev python3-venv xdotool
    

    Fedora 40+:

    sudo dnf install -y python3-pip python3-gobject gtk3 ibus-devel \
         gobject-introspection-devel glib2-devel python3-devel portaudio-devel \
         cairo-devel cairo-gobject-devel libffi-devel python3-virtualenv pkg-config cmake \
         gcc-c++ make xdotool
    

    AppIndicator (system tray):

    # Older Ubuntu:
    sudo apt install -y gir1.2-appindicator3-0.1
    # Debian 12+ or newer Ubuntu:
    sudo apt install -y gir1.2-ayatanaappindicator3-0.1
    

    macOS (tooling only): brew install portaudio pkg-config; use xcode-select --install if a C compiler is missing. PyGObject/pycairo and their header checks apply only on Linux, which is required to run the desktop app.

  3. Create the environment and install:

    # Requires uv (https://docs.astral.sh/uv/); creates .venv/ with dev + vad extras
    just deps
    

    Missing native build headers are reported with install commands before syncing. For older Linux releases, use the installer environment described below.

  4. Run:

    just run-source-debug
    
  5. Optional pre-commit hooks:

    uv run --no-sync pre-commit install
    

    Hooks are optional. CI runs the same checks.

The two environments

The repository uses two virtual environments on purpose. Do not merge them:

Directory Created by Python Used for
.venv/ just deps (uv) pinned in .python-version dev tooling: pytest, black, mypy, just recipes
venv/ ./install.sh the system Python running the installed app, which needs distro PyGObject
  • On Linux, .venv/ builds the locked PyGObject, requiring glib 2.80+ and the headers above. On Debian 12 or Fedora 39 and older, use ./install.sh --dev, then venv/bin/pytest or venv/bin/python -m vocalinux.main --debug instead.
  • venv/ uses distro PyGObject via --system-site-packages. The installer ignores an activated venv and rebuilds one created by the wrong interpreter. It uses /usr/bin/python3 unless overridden, e.g. SYSTEM_PYTHON=/usr/bin/python3.12 ./install.sh.

Making changes

Branch naming

git checkout main
git pull origin main
git checkout -b feature/your-feature-name
# or fix/, docs/, refactor/, test/

Never push directly to main. Open a pull request for every change.

Code style

Tool Role
Black Formatting (line length 100)
isort Import sorting (black profile)
flake8 Linting
mypy Type checking (just typecheck)
just format    # black + isort
just lint      # flake8 + black --check + isort --check
just typecheck # mypy src/

Project structure

voculinux/
├── src/vocalinux/            # Application
│   ├── main.py
│   ├── speech_recognition/   # Engines + command processor
│   ├── text_injection/       # X11 / Wayland injection
│   ├── ui/                   # GTK tray, settings, config
│   └── utils/
├── tests/
├── resources/                # Icons and sounds
├── docs/
├── install.d/                # Installer modules, including generated package data
├── packaging/                # Packaging inputs; Void xbps is the published channel
├── scripts/                  # Maintenance tools and distro package-map source
├── snap/                     # Snap recipe (not published for Voculinux)
└── web/                      # Marketing site (Next.js)
Task Start here
Voice command src/vocalinux/speech_recognition/command_processor.py
UI src/vocalinux/ui/
Recognition engines src/vocalinux/speech_recognition/recognition_manager.py
Text injection src/vocalinux/text_injection/text_injector.py
Settings / config src/vocalinux/ui/config_manager.py, settings_dialog.py
Installer package names scripts/distro-package-map.yaml

Installer package map

scripts/distro-package-map.yaml is the source of truth for package names, alternatives, and conditional package probes used by install.sh. Do not edit the generated install.d/package_map.sh directly. After changing the YAML, run:

just distro-packages
just distro-packages-check

Commit both the YAML and generated shell module. Package-manager control flow and installation policy remain handwritten in install.d/system_dependencies.sh; user systems never parse the YAML. The remote bootstrap's pre-checkout git installation is the deliberate exception because the generated module is not available yet.

Testing

just test
just test-cov
uv run --extra dev --extra vad --group lint pytest tests/test_command_processor.py
  • Place tests in tests/ as test_*.py
  • Aim for solid coverage on new code (roughly 80%+)
  • Use pytest-mock via the mocker fixture
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"

Remote API test server

python scripts/test_remote_server.py
python scripts/test_remote_server.py --port 9000
python scripts/test_remote_server.py --delay 2

Endpoints:

  • whisper.cpp style: http://localhost:8080/inference
  • OpenAI-compatible: http://localhost:8080/v1/audio/transcriptions

In Settings → Speech Model, select Remote API, set the server URL, choose the endpoint format, and use Test Connection.

Pull requests

Automated agents may append three robot emoji (🤖) to the PR title to opt into the agent fast-track merge path when that process is active.

Before you open a PR

  • Style checks pass (just lint, just typecheck)
  • Tests pass (just test)
  • Docs updated when behavior or install steps change
  • Commits use Conventional Commits
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

Submit

  1. Push your branch to your fork
  2. Open a PR against main and fill out the template
  3. Link related issues
  4. Wait for CI; address review feedback
  5. Maintainers squash-merge when approved

Releases

Maintainers follow docs/RELEASE_PROCESS.md (version files, docs, website, tag, automated publish). Do not tag releases from feature branches.

Community

License

Contributions are licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). By opening a pull request, you agree that your contribution may be distributed under that license.

Voculinux is a hard fork of Vocalinux by VocaHQ: https://github.com/VocaHQ/vocalinux