feat(identity): rename user-visible identity to voculinux with one-time legacy import

The fork takes its own name everywhere a user can see it: binaries
(voculinux, voculinux-gui), desktop entry, autostart, tray, D-Bus
namespace (com.voculinux.Voculinux, no alias for the old name),
config/data/cache dirs, single-instance lock, IBus engine identity,
tray icons, resource prefixes, VOCULINUX_* environment names, and the
update-checker user agent. The internal Python module stays vocalinux
and the distribution metadata keeps the upstream URLs as provenance.

On first run a previous Vocalinux install's config.json, custom
dictionary, and portal restore token are copied once into the new
locations (new config always wins, no merge, no write-back); models
re-resolve through the pinned-checksum download path. An offline
naming-sweep test proves no old-name strings remain on user-visible
surfaces outside the allowlist.

Refs #18
This commit is contained in:
soubarnak
2026-11-06 01:29:39 +05:30
parent c565e6d946
commit ea7be5f111
251 changed files with 2449 additions and 1991 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
# Architecture
Vocalinux is a GTK 3 desktop application. `main.py` wires together the
Voculinux is a GTK 3 desktop application. `main.py` wires together the
configuration manager, recognition manager, tray UI, D-Bus service, and text
injector. Audio capture and recognition run outside the GTK event loop.
@@ -104,7 +104,7 @@ as `tray_indicator.py`, `dictation_overlay.py`, `transcription_history.py`,
## Services and optional integrations
`dbus_service.py` owns the `com.vocalinux.Vocalinux` session-bus name and
`dbus_service.py` owns the `com.voculinux.Voculinux` session-bus name and
provides Toggle, Start, and Stop methods for external controls.
`gateway_embed/` manages the optional local VocaGateway container lifecycle,
status, pairing, and configuration. It is separate from the default
+10 -10
View File
@@ -3,13 +3,13 @@
## Users
```bash
yay -S vocalinux # canonical release sdist, built against Arch dependencies
yay -S vocalinux-git # community package; tracks main
yay -S voculinux # canonical release sdist, built against Arch dependencies
yay -S voculinux-git # community package; tracks main
```
`vocalinux`, `vocalinux-bin` and `vocalinux-git` conflict; install only one.
`voculinux`, `voculinux-bin` and `voculinux-git` conflict; install only one.
`packaging/aur/vocalinux-bin/` builds a `-bin` variant that installs the
`packaging/aur/voculinux-bin/` builds a `-bin` variant that installs the
prebuilt AppImage from the release — no Python, engine, or GPU dependency
builds, since the bundle carries them (#817). Its publication waits only for
release creation and both AppImages, not the source-package gate or other
@@ -19,7 +19,7 @@ then pushes to AUR in the `Publish AUR -bin package` step.
## Maintainers (one-time setup)
Release tags prepare and test the source PKGBUILD from
`packaging/aur/vocalinux/PKGBUILD`, then auto-push the verified file when these
`packaging/aur/voculinux/PKGBUILD`, then auto-push the verified file when these
secrets exist:
| Secret | Value |
@@ -30,16 +30,16 @@ secrets exist:
```bash
# 1. AUR account + SSH pubkey: https://aur.archlinux.org/register
ssh-keygen -t ed25519 -C "vocalinux-aur" -f ./aur_ed25519 -N ""
ssh-keygen -t ed25519 -C "voculinux-aur" -f ./aur_ed25519 -N ""
# upload aur_ed25519.pub on AUR; put aur_ed25519 in AUR_SSH_PRIVATE_KEY
# 2. Create empty package once
git clone ssh://aur@aur.archlinux.org/vocalinux.git
git clone ssh://aur@aur.archlinux.org/voculinux.git
# 3. Next v* tag runs Publish to AUR (skipped if secret missing)
```
Sources: `packaging/aur/vocalinux/PKGBUILD`. Community git package: https://aur.archlinux.org/packages/vocalinux-git
Sources: `packaging/aur/voculinux/PKGBUILD`. Community git package: https://aur.archlinux.org/packages/voculinux-git
## Source archive and trust model
@@ -91,7 +91,7 @@ Only after this succeeds is `aur-source-pkgbuild` uploaded for `publish-aur`.
Publication downloads that exact file; there is no version rewrite or
`updpkgsums` afterwards. The gate runs even without AUR credentials; only the
final push is secret-gated. This intentionally makes source publication wait
for the release's checksums and attestations. `vocalinux-bin` uses a separate
for the release's checksums and attestations. `voculinux-bin` uses a separate
AppImage publication path independent of this source gate and the global
checksum job; its PR smoke still uses a stub AppImage.
@@ -107,7 +107,7 @@ What those providers actually ship remains a separate monitoring question.
**`ERROR Missing dependencies: setuptools<82`**
The AUR package builds with `python -m build --wheel --no-isolation`, so it uses Arch extra `python-setuptools` (currently 84). Vocalinux 0.16.1 drops the `<82` cap in `pyproject.toml`. Rebuild 0.16.1 or later.
The AUR package builds with `python -m build --wheel --no-isolation`, so it uses Arch extra `python-setuptools` (currently 84). Voculinux 0.16.1 drops the `<82` cap in `pyproject.toml`. Rebuild 0.16.1 or later.
**`'_pywhispercpp.whisper_full_params' object has no attribute 'context_params'`**
+9 -9
View File
@@ -16,13 +16,13 @@ would make the external terms contract surprising.
## File contracts
Both files live in VocaLinux's XDG-aware configuration directory:
`$XDG_CONFIG_HOME/vocalinux` (or `~/.config/vocalinux` when unset).
Both files live in Voculinux's XDG-aware configuration directory:
`$XDG_CONFIG_HOME/voculinux` (or `~/.config/voculinux` when unset).
| File | Contract | Consumer |
| --- | --- | --- |
| `dictionary.txt` | UTF-8 (BOM accepted), one term per line. Blank lines and lines beginning with `#` are ignored. Terms are de-duplicated case-insensitively while retaining the first spelling. | VocaLinux and an external accessibility scanner. |
| `custom-dictionary-corrections.json` | UTF-8 JSON object: `{"version": 1, "corrections": [{"heard": "super base", "replacement": "Supabase"}]}`. | VocaLinux only. |
| `dictionary.txt` | UTF-8 (BOM accepted), one term per line. Blank lines and lines beginning with `#` are ignored. Terms are de-duplicated case-insensitively while retaining the first spelling. | Voculinux and an external accessibility scanner. |
| `custom-dictionary-corrections.json` | UTF-8 JSON object: `{"version": 1, "corrections": [{"heard": "super base", "replacement": "Supabase"}]}`. | Voculinux only. |
The terms file remains deliberately simple and scanner-friendly. Corrections
need two unambiguous fields, a version, and exact replacement casing, so JSON is
@@ -35,7 +35,7 @@ edited file therefore takes effect on the next dictation segment without an app
restart. Missing, unreadable, malformed, or unsupported correction files are
ignored safely; dictation continues without their entries.
The terms file may contain any number of lines, but VocaLinux limits a single
The terms file may contain any number of lines, but Voculinux limits a single
prompt to the first 200 valid terms and 2,000 characters. This bounds decoding
work while leaving the scanner's complete line-file contract intact. The Custom
Dictionary page keeps both an add/remove editor and a validated file chooser
@@ -43,7 +43,7 @@ for the terms file.
## Processing and engine behavior
For every completed audio segment, VocaLinux applies this order:
For every completed audio segment, Voculinux applies this order:
1. The selected engine transcribes audio.
2. Live phrase corrections run against the raw transcript.
@@ -78,7 +78,7 @@ the JSON corrections file exists; it is never silently deleted or migrated.
The #767 persisted configuration keys are retained unchanged:
`dictionary.enabled`, `dictionary.file_path` (default
`~/.config/vocalinux/dictionary.txt`), and `dictionary.max_words`. Existing
`~/.config/voculinux/dictionary.txt`), and `dictionary.max_words`. Existing
Peony settings therefore continue to select the scanner's `dictionary.txt`
file. New configured paths are accepted only when they can be expanded and are
either absent (so the UI can create them) or readable regular files; a failed
@@ -99,7 +99,7 @@ paths are safely ignored and shown as unavailable rather than raising.
## Human test checklist
1. Add `VocaLinux`, `PyGObject`, and a non-ASCII term in **Custom terms**;
1. Add `Voculinux`, `PyGObject`, and a non-ASCII term in **Custom terms**;
confirm `dictionary.txt` is UTF-8, one line per term, and an external
edit changes the next Whisper, whisper.cpp, and Faster Whisper dictation segment.
2. Add `super base` → `Supabase`; test lowercase, uppercase, punctuation, an
@@ -108,7 +108,7 @@ paths are safely ignored and shown as unavailable rather than raising.
3. With voice commands enabled, add a correction that changes a command-like
misrecognition into ordinary text. Confirm it is injected rather than acted
on. Also verify an intentionally command-like replacement is avoided.
4. Edit each file externally while VocaLinux is running. Test an invalid JSON
4. Edit each file externally while Voculinux is running. Test an invalid JSON
correction file and invalid UTF-8 terms file; confirm dictation continues and
the Settings status/save feedback is clear.
5. Test the UI with keyboard only: Add buttons via Enter, empty validation,
+42 -42
View File
@@ -1,8 +1,8 @@
# Linux distribution compatibility
How Vocalinux behaves across distributions, what is tested, and what to install manually when needed.
How Voculinux behaves across distributions, what is tested, and what to install manually when needed.
For install steps, prefer [INSTALL.md](INSTALL.md). Flatpak packaging (useful on immutable or non-standard layouts): [packaging/flatpak/README.md](../packaging/flatpak/README.md). Snap Store listing: [snapcraft.io/vocalinux](https://snapcraft.io/vocalinux) (`--edge`; pack/upload steps in [INSTALL.md](INSTALL.md)). Flatpak is not on Flathub: submission [flathub#9368](https://github.com/flathub/flathub/pull/9368) closed 2026-07-23 on policy grounds; channel tracked in [#167](https://github.com/VocaHQ/vocalinux/issues/167).
For install steps, prefer [INSTALL.md](INSTALL.md). Flatpak packaging (useful on immutable or non-standard layouts): [packaging/flatpak/README.md](../packaging/flatpak/README.md). Snap Store listing: [snapcraft.io/voculinux](https://snapcraft.io/voculinux) (`--edge`; pack/upload steps in [INSTALL.md](INSTALL.md)). Flatpak is not on Flathub: submission [flathub#9368](https://github.com/flathub/flathub/pull/9368) closed 2026-07-23 on policy grounds; channel tracked in [#167](https://github.com/VocaHQ/vocalinux/issues/167).
## Cross-distro behavior
@@ -24,7 +24,7 @@ The installer uses a multi-step approach to detect the correct GI_TYPELIB_PATH:
### Wrapper Scripts
The installer creates wrapper scripts (`~/.local/bin/vocalinux` and `~/.local/bin/vocalinux-gui`) that:
The installer creates wrapper scripts (`~/.local/bin/voculinux` and `~/.local/bin/voculinux-gui`) that:
- Set the correct `GI_TYPELIB_PATH` environment variable
- Handle input group permissions for Wayland keyboard shortcuts
- Provide seamless cross-distro compatibility
@@ -35,7 +35,7 @@ The `.desktop` entry is automatically configured with the detected `GI_TYPELIB_P
## Officially Supported Distributions
These distributions are tested and known to work well with Vocalinux. A
These distributions are tested and known to work well with Voculinux. A
derivative is judged by the Python and package repositories it ships rather
than by its own version number, which rarely tracks the base release. In
particular, `install.sh` does not interpret a Debian-based derivative's product
@@ -94,7 +94,7 @@ sudo apt install -y python3-gi gir1.2-gtk-3.0 gir1.2-ibus-1.0 gir1.2-gdkpixbuf-2
### Debian-specific notes
Debian's standard repositories differ from Ubuntu in a few ways that matter for Vocalinux:
Debian's standard repositories differ from Ubuntu in a few ways that matter for Voculinux:
**pywhispercpp build prerequisites.** On a clean Debian install the following packages are not
pulled in transitively (unlike Ubuntu) but are required when `pywhispercpp` must be compiled
@@ -125,16 +125,16 @@ package-scoped flag to avoid compiling unrelated deps like NumPy from source (wh
long time and can fail):
```bash
source ~/.local/share/vocalinux/venv/bin/activate
source ~/.local/share/voculinux/venv/bin/activate
PYWHISPERCPP_CLEAN=1 pip install --force-reinstall --no-binary=pywhispercpp pywhispercpp
deactivate
```
**Verifying libwhisper.so resolution.** If Vocalinux starts with
**Verifying libwhisper.so resolution.** If Voculinux starts with
`libwhisper.so.1: cannot open shared object file`, check for unresolved symbols:
```bash
ldd $(find ~/.local/share/vocalinux/venv -name '*.so' -path '*/pywhispercpp*' 2>/dev/null | head -1) | grep 'not found'
ldd $(find ~/.local/share/voculinux/venv -name '*.so' -path '*/pywhispercpp*' 2>/dev/null | head -1) | grep 'not found'
```
If any libraries are listed, re-run the installer with `--rebuild-whispercpp` or switch to
@@ -215,11 +215,11 @@ sudo urpmi -y python3-gobject gtk3-devel gobject-introspection-devel \
## PyPI, pip, and pipx Installation
The PyPI package is useful when you want a standard Python package install, or
when you want to manage Vocalinux with `pipx`. However, **Vocalinux requires
when you want to manage Voculinux with `pipx`. However, **Voculinux requires
system desktop packages** that cannot be installed by pip or pipx.
Use the official installer when possible. It installs the required system
packages, creates the virtual environment, installs Vocalinux, sets up desktop
packages, creates the virtual environment, installs Voculinux, sets up desktop
integration, and downloads the default speech model:
```bash
@@ -229,8 +229,8 @@ bash /tmp/vl.sh
### Important: Install System Packages First
Before running `pip install vocalinux`, `pip install "vocalinux[vosk]"`, or
`pipx install vocalinux`, you **must** install the required system packages:
Before running `pip install voculinux`, `pip install "voculinux[vosk]"`, or
`pipx install voculinux`, you **must** install the required system packages:
#### Ubuntu/Debian
```bash
@@ -272,8 +272,8 @@ sudo zypper install "${PYVER}-gobject" "${PYVER}-gobject-cairo" gtk3 ibus typeli
2. **Create a virtual environment with system site-packages enabled**:
```bash
python3 -m venv ~/.local/share/vocalinux-pypi/venv --system-site-packages
source ~/.local/share/vocalinux-pypi/venv/bin/activate
python3 -m venv ~/.local/share/voculinux-pypi/venv --system-site-packages
source ~/.local/share/voculinux-pypi/venv/bin/activate
pip install --upgrade pip setuptools wheel
```
@@ -281,15 +281,15 @@ sudo zypper install "${PYVER}-gobject" "${PYVER}-gobject-cairo" gtk3 ibus typeli
as `python3-gi`, which are often more reliable than building PyGObject from
source in a venv.
3. **Install Vocalinux from PyPI**:
3. **Install Voculinux from PyPI**:
```bash
pip install vocalinux
# vosk engine: pip install "vocalinux[vosk]"
pip install voculinux
# vosk engine: pip install "voculinux[vosk]"
```
4. **Run Vocalinux**:
4. **Run Voculinux**:
```bash
vocalinux
voculinux
```
### pipx Installation Steps
@@ -311,20 +311,20 @@ sudo zypper install "${PYVER}-gobject" "${PYVER}-gobject-cairo" gtk3 ibus typeli
pipx ensurepath
```
3. **Install Vocalinux**:
3. **Install Voculinux**:
```bash
pipx install vocalinux
# vosk engine: pipx install "vocalinux[vosk]"
pipx install voculinux
# vosk engine: pipx install "voculinux[vosk]"
```
4. **Run Vocalinux**:
4. **Run Voculinux**:
```bash
vocalinux
voculinux
```
### Why System Packages Are Required
Vocalinux uses GTK3 for its GUI, AppIndicator/Ayatana for the system tray icon,
Voculinux uses GTK3 for its GUI, AppIndicator/Ayatana for the system tray icon,
PortAudio for microphone capture, and tools such as `xdotool`, `wtype`, and clipboard utilities (`wl-clipboard`, `xclip`, `xsel`) for
text injection and layout-independent Wayland paste fallback. These are system libraries and desktop tools that must be
installed with your distribution's package manager. Python packages from PyPI
@@ -333,20 +333,20 @@ typelibs, tray support, audio development libraries, or text injection binaries.
### Troubleshooting pip/pipx Installation
If `vocalinux` fails to start:
If `voculinux` fails to start:
1. **Check for missing system packages** - The error message will indicate which packages are missing
2. **Verify GI_TYPELIB_PATH** - In rare cases, you may need to set this environment variable:
```bash
export GI_TYPELIB_PATH=/usr/lib/x86_64-linux-gnu/girepository-1.0
vocalinux
voculinux
```
3. **Check package metadata** - Run `pip show vocalinux` or
`pipx runpip vocalinux show vocalinux` to confirm which version was installed.
3. **Check package metadata** - Run `pip show voculinux` or
`pipx runpip voculinux show voculinux` to confirm which version was installed.
4. **Check Python dependencies** - Run `pip check` inside the venv, or
`pipx runpip vocalinux check` for pipx.
`pipx runpip voculinux check` for pipx.
If Vocalinux reports that a speech recognition model is missing, open Settings
If Voculinux reports that a speech recognition model is missing, open Settings
and download a model, or use the official installer to download the default model
during setup.
@@ -362,7 +362,7 @@ This installer automatically detects your distribution and installs all required
## Text Injection Tools
Vocalinux requires text injection tools to work with X11 or Wayland:
Voculinux requires text injection tools to work with X11 or Wayland:
### For X11
- **xdotool**: Required for X11 sessions
@@ -370,7 +370,7 @@ Vocalinux requires text injection tools to work with X11 or Wayland:
### For Wayland
- **IBus**: Recommended for KDE Plasma Wayland and generally the most reliable direct text input path
- **wtype**: Recommended for wlroots-style Wayland compositors such as sway
- **ydotool**: Universal alternative that works with both X11 and Wayland. Current distro packages use the per-user `ydotool.service`; source builds can install the system-level `ydotoold.service`. Vocalinux uses clipboard paste with `wl-clipboard`, `xclip`, or `xsel` to avoid non-US layout scrambling.
- **ydotool**: Universal alternative that works with both X11 and Wayland. Current distro packages use the per-user `ydotool.service`; source builds can install the system-level `ydotoold.service`. Voculinux uses clipboard paste with `wl-clipboard`, `xclip`, or `xsel` to avoid non-US layout scrambling.
- **xdotool**: May work via XWayland fallback
### Installation by Distribution
@@ -383,7 +383,7 @@ sudo zypper install xdotool wtype wl-clipboard xclip xsel # openSUSE
```
Ubuntu releases which package `ydotool` install a **user** unit named
`ydotool.service`. Enable it only for the account running Vocalinux:
`ydotool.service`. Enable it only for the account running Voculinux:
```bash
sudo apt install ydotool
@@ -443,13 +443,13 @@ For unsupported or experimental distributions:
### Autostart Compatibility
Vocalinux uses **XDG autostart desktop entries** for "Start on Login".
Voculinux uses **XDG autostart desktop entries** for "Start on Login".
- Desktop-session autostart file location:
- `$XDG_CONFIG_HOME/autostart/vocalinux.desktop`, or
- `~/.config/autostart/vocalinux.desktop` (fallback)
- This launches Vocalinux as a user GUI app after login.
- Vocalinux does **not** create a `systemd` service/unit for this feature.
- `$XDG_CONFIG_HOME/autostart/voculinux.desktop`, or
- `~/.config/autostart/voculinux.desktop` (fallback)
- This launches Voculinux as a user GUI app after login.
- Voculinux does **not** create a `systemd` service/unit for this feature.
Practical caveat:
@@ -500,7 +500,7 @@ When reporting issues, please include:
5. **Error messages or logs:**
- Any error messages from the installer
- Output from running `vocalinux-gui` from terminal
- Output from running `voculinux-gui` from terminal
- Relevant journal logs if applicable
6. **Steps to reproduce:**
@@ -525,7 +525,7 @@ Use this checklist when testing on a new distribution:
- [ ] Check wrapper scripts exist
### Post-Install
- [ ] Launch from terminal: `~/.local/bin/vocalinux-gui`
- [ ] Launch from terminal: `~/.local/bin/voculinux-gui`
- [ ] Launch from application menu
- [ ] Verify tray icon appears
- [ ] Test keyboard shortcuts (Hold Right Alt by default)
@@ -543,7 +543,7 @@ Use this checklist when testing on a new distribution:
## Contributing Compatibility Fixes
If you successfully get Vocalinux working on an unsupported or experimental distribution:
If you successfully get Voculinux working on an unsupported or experimental distribution:
1. Test thoroughly using the checklist above
2. Document any distribution-specific requirements
+17 -17
View File
@@ -1,13 +1,13 @@
# Self-hosted Flatpak remote
Vocalinux publishes a signed OSTree Flatpak remote on every stable `v*` tag —
Voculinux publishes a signed OSTree Flatpak remote on every stable `v*` tag —
the Homebrew-tap analogue to `VocaHQ/homebrew-vocamac`
([issue #785](https://github.com/VocaHQ/vocalinux/issues/785)). The remote
lives in the dedicated repo `VocaHQ/vocalinux-flatpak`, served by GitHub
Pages:
```bash
flatpak install https://vocahq.github.io/vocalinux-flatpak/com.vocalinux.Vocalinux.flatpakref
flatpak install https://vocahq.github.io/voculinux-flatpak/com.voculinux.Voculinux.flatpakref
flatpak update # picks up each new release
```
@@ -18,8 +18,8 @@ steps:
```bash
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
flatpak remote-add --if-not-exists vocahq https://vocahq.github.io/vocalinux-flatpak/vocahq.flatpakrepo
flatpak install vocahq com.vocalinux.Vocalinux
flatpak remote-add --if-not-exists vocahq https://vocahq.github.io/voculinux-flatpak/vocahq.flatpakrepo
flatpak install vocahq com.voculinux.Voculinux
```
Only the app is ours; the GNOME runtime still comes from Flathub —
@@ -38,7 +38,7 @@ prerelease tags, which never reach the remote.
3. **Signing key** — OSTree remotes sign the summary and commits with GPG:
```bash
gpg --quick-gen-key "Vocalinux Flatpak <flatpak@vocahq.com>" ed25519 sign never
gpg --quick-gen-key "Voculinux Flatpak <flatpak@vocahq.com>" ed25519 sign never
gpg --list-secret-keys # note the KEYID
gpg --export-secret-keys --armor KEYID # -> FLATPAK_GPG_PRIVATE_KEY
gpg --gen-revoke KEYID > flatpak-remote-revoke.asc # store it somewhere safe
@@ -59,12 +59,12 @@ prerelease tags, which never reach the remote.
- `FLATPAK_REMOTE_REPO` — publish target (default
`VocaHQ/vocalinux-flatpak`)
- `FLATPAK_REMOTE_URL` — remote URL baked into the `.flatpakrepo`
(default `https://vocahq.github.io/vocalinux-flatpak/repo`; set
e.g. `https://flatpak.vocalinux.com/repo` for a custom domain)
(default `https://vocahq.github.io/voculinux-flatpak/repo`; set
e.g. `https://flatpak.voculinux.com/repo` for a custom domain)
- `FLATPAKREPO_URL` — where users fetch `vocahq.flatpakrepo` (default
`https://vocahq.github.io/vocalinux-flatpak/vocahq.flatpakrepo`)
`https://vocahq.github.io/voculinux-flatpak/vocahq.flatpakrepo`)
- `FLATPAKREF_URL` — where users fetch the app `.flatpakref` (default
`https://vocahq.github.io/vocalinux-flatpak/com.vocalinux.Vocalinux.flatpakref`)
`https://vocahq.github.io/voculinux-flatpak/com.voculinux.Voculinux.flatpakref`)
6. **Trigger** — push a stable `v*` tag (alpha/beta/rc tags do not publish to
the remote), or re-run `publish-flatpak-remote` on an existing release run
after configuring the secrets.
@@ -77,7 +77,7 @@ an unconfigured remote never fails a release.
`release.yml → publish-flatpak-remote` runs on stable tags only, after the
GitHub Release exists and the two arch builds finish:
1. Downloads `Vocalinux-<version>-{x86_64,aarch64}.flatpak` from the build
1. Downloads `Voculinux-<version>-{x86_64,aarch64}.flatpak` from the build
jobs.
2. Probes the remote repo for an existing `gh-pages` branch; only a confirmed
first publish may skip the history checkout — a transient failure aborts
@@ -90,7 +90,7 @@ GitHub Release exists and the two arch builds finish:
4. `flatpak build-update-repo --generate-static-deltas --gpg-sign
--gpg-import` rebuilds the summary, signs it, and generates static deltas.
5. Regenerates `vocahq.flatpakrepo` (URL + base64 public key),
`com.vocalinux.Vocalinux.flatpakref` (the one-command app ref carrying the
`com.voculinux.Voculinux.flatpakref` (the one-command app ref carrying the
`RuntimeRepo=` pointer to Flathub), `vocahq.gpg` (the bare public key, for
the key-rotation path below), and the index page from
`packaging/flatpak/index.html`.
@@ -101,10 +101,10 @@ GitHub Release exists and the two arch builds finish:
```bash
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
flatpak remote-add --if-not-exists vocahq https://vocahq.github.io/vocalinux-flatpak/vocahq.flatpakrepo
flatpak remote-info vocahq com.vocalinux.Vocalinux # signed commit, both arches
flatpak install vocahq com.vocalinux.Vocalinux
flatpak run com.vocalinux.Vocalinux
flatpak remote-add --if-not-exists vocahq https://vocahq.github.io/voculinux-flatpak/vocahq.flatpakrepo
flatpak remote-info vocahq com.voculinux.Voculinux # signed commit, both arches
flatpak install vocahq com.voculinux.Voculinux
flatpak run com.voculinux.Voculinux
# after the next tag: flatpak update pulls the delta
```
@@ -121,7 +121,7 @@ does nothing at all), and `flatpak update` fails verification until the key
is updated. Point users at the public key published beside the repo:
```bash
curl -fsSL https://vocahq.github.io/vocalinux-flatpak/vocahq.gpg -o /tmp/vocahq.gpg
curl -fsSL https://vocahq.github.io/voculinux-flatpak/vocahq.gpg -o /tmp/vocahq.gpg
flatpak remote-modify --gpg-import=/tmp/vocahq.gpg vocahq
flatpak update
```
@@ -133,7 +133,7 @@ their `vocahq` origin and update normally afterwards):
```bash
flatpak remote-delete --force vocahq # --force: the remote is still in use
flatpak remote-add vocahq https://vocahq.github.io/vocalinux-flatpak/vocahq.flatpakrepo
flatpak remote-add vocahq https://vocahq.github.io/voculinux-flatpak/vocahq.flatpakrepo
flatpak update
```
+9 -9
View File
@@ -1,6 +1,6 @@
# Local VocaGateway from Vocalinux (optional)
# Local VocaGateway from Voculinux (optional)
Vocalinux can start a **local** [VocaGateway](https://github.com/VocaHQ/vocagateway)
Voculinux can start a **local** [VocaGateway](https://github.com/VocaHQ/vocagateway)
container from **Settings → Speech Model → Advanced**, next to Remote Server. This is an
optional power-user path. It is **not** on-device processing: microphone audio
still leaves the desktop client and is transcribed by the gateway process on
@@ -8,23 +8,23 @@ your machine (or LAN).
The default speech engine remains **whisper.cpp** on-device. Enabling a local
gateway never changes that default by itself. Use **Use this Gateway** only when
you want Vocalinux to talk to the gateway over the existing Remote API settings
you want Voculinux to talk to the gateway over the existing Remote API settings
(`remote_api_*`, endpoint `/v1/audio/transcriptions`). See [HTTP_REMOTE.md](HTTP_REMOTE.md).
## Requirements (Linux MVP)
- **podman** (preferred) or **docker**, with a working `compose` plugin (or
`podman-compose` / `docker-compose`).
- Vocalinux does **not** bundle a container engine inside the AppImage.
- Voculinux does **not** bundle a container engine inside the AppImage.
- **Flatpak**: the sandbox cannot reach the host container socket. Run the
native package or AppImage, or start VocaGateway on the host yourself and
point Remote Server at it.
## What Vocalinux does
## What Voculinux does
1. Pins upstream **VocaGateway `v0.1.0`** (git tag) under your XDG cache and uses
that checkout's `compose.yaml` with Compose project name `vocagateway`.
2. Writes a private bootstrap token under `~/.config/vocalinux/gateway_embed/`
2. Writes a private bootstrap token under `~/.config/voculinux/gateway_embed/`
(mode `600`) and a matching Compose `.env`.
3. Runs `compose -f compose.yaml --profile cpu up -d` for the `gateway` service.
The v0.1.0 GitHub release has no published container image assets, so the first
@@ -55,18 +55,18 @@ By default the published host is `127.0.0.1` (desktop-only). Turn on **Allow LAN
access for Phone** to set `VOCAGATEWAY_PUBLISH_HOST=0.0.0.0` and to advertise a
LAN URL in pairing. Open port `8765` in your firewall only on trusted networks.
Never put `127.0.0.1` / `localhost` in the phone QR. If a LAN toggle fails,
compose keeps the previous bind, Vocalinux restores the embed `.env`, and the
compose keeps the previous bind, Voculinux restores the embed `.env`, and the
switch snaps back with an error (Stop and Run again, or retry).
## Tray and Quit
The tray menu offers **Stop local Gateway** whenever compose is actually running
(Starting, Live, Pairable, Ready, or Error), including a leftover from a previous
Vocalinux session. Vocalinux does not auto-start the gateway on login in v1.
Voculinux session. Voculinux does not auto-start the gateway on login in v1.
**Quit does not stop compose.** The pinned compose file uses `restart:
unless-stopped`, so a LAN-published gateway on `0.0.0.0:8765` keeps running after
you quit Vocalinux. The next launch restores the Allow LAN switch from the running
you quit Voculinux. The next launch restores the Allow LAN switch from the running
compose publish host. Use **Stop local Gateway** in Settings or the tray when you
want it gone. Do not assume Quit tears it down.
+19 -19
View File
@@ -1,8 +1,8 @@
# Remote HTTP transcription
Vocalinux can offload speech recognition to a remote HTTP server instead of running a local model. Use this when you want faster transcription on a more powerful machine, to share one model across clients, or to keep a laptop free of GPU/model overhead.
Voculinux can offload speech recognition to a remote HTTP server instead of running a local model. Use this when you want faster transcription on a more powerful machine, to share one model across clients, or to keep a laptop free of GPU/model overhead.
Vocalinux speaks two wire formats out of the box:
Voculinux speaks two wire formats out of the box:
- **OpenAI-compatible**: `POST /v1/audio/transcriptions` (e.g. OpenAI, [Speaches](https://github.com/speaches-ai/speaches), LocalAI, FunASR/SenseVoice)
- **whisper.cpp server**: `POST /inference` (the binary shipped with [whisper.cpp](https://github.com/ggerganov/whisper.cpp))
@@ -17,7 +17,7 @@ On Linux you can start an optional local [VocaGateway](https://github.com/VocaHQ
## How it works
When the **Remote API** engine is active, Vocalinux:
When the **Remote API** engine is active, Voculinux:
1. Captures microphone audio locally (16 kHz, mono, 16-bit PCM).
2. On end-of-utterance, packages the buffer as a WAV file in memory.
@@ -61,7 +61,7 @@ The endpoint is `/v1/audio/transcriptions`.
[FunASR](https://github.com/modelscope/FunASR) can run a local
OpenAI-compatible transcription service, which keeps audio on your own machine
or LAN while letting Vocalinux use SenseVoice or Paraformer-family models:
or LAN while letting Voculinux use SenseVoice or Paraformer-family models:
```bash
pip install 'torch>=2.13.0' torchaudio
@@ -70,7 +70,7 @@ funasr-server --device cuda
```
The server listens on `http://localhost:8000` by default and exposes
`POST /v1/audio/transcriptions`. In Vocalinux, set:
`POST /v1/audio/transcriptions`. In Voculinux, set:
- **Server URL**: `http://localhost:8000`
- **API Endpoint**: `OpenAI/FunASR (/v1/audio/transcriptions)`
@@ -78,7 +78,7 @@ The server listens on `http://localhost:8000` by default and exposes
Use `--device cpu` for CPU-only testing if your FunASR install supports it. A
remote GPU host works too: bind the server to the LAN interface, open the port,
and point Vocalinux at that host.
and point Voculinux at that host.
### Network checklist
@@ -87,26 +87,26 @@ and point Vocalinux at that host.
- For anything outside a trusted LAN, terminate TLS in front of the server (Caddy, nginx, Traefik) and require an API key. The audio you upload is private speech.
- If you also use the server from a mobile dictation app, terminate TLS even on a LAN. Most Android and iOS apps refuse cleartext HTTP.
## Client-side setup (Vocalinux)
## Client-side setup (Voculinux)
### Via the Settings dialog
The remote engine is a power-user option in the **Speech Engine** settings.
1. Launch Vocalinux and open **Settings → Speech Engine → Remote Server**.
1. Launch Voculinux and open **Settings → Speech Engine → Remote Server**.
2. Toggle **Use remote server** on. This overrides whatever local engine is selected above it.
3. Fill in the fields:
- **Server URL**: base URL of the server, e.g. `http://192.168.1.100:8080` (no trailing slash needed; one is stripped automatically).
- **API Key** (optional): sent as `Authorization: Bearer <key>`. Leave blank if your server doesn't require auth.
- **API Endpoint**: pick **Whisper.cpp (`/inference`)** or **OpenAI/FunASR (`/v1/audio/transcriptions`)** to match your server.
- **Model**: model identifier sent to OpenAI-compatible servers. Use `whisper-1` for classic Whisper servers, or `sensevoice` for FunASR/SenseVoice.
4. Click **Test Connection**. Success means the URL is reachable and credentials (if any) are accepted. A failure here is only a warning; Vocalinux will try again on the first transcription.
4. Click **Test Connection**. Success means the URL is reachable and credentials (if any) are accepted. A failure here is only a warning; Voculinux will try again on the first transcription.
Settings auto-save and re-initialise the engine immediately, so you can start dictating as soon as the test passes. Toggling the switch off restores the local engine selected on the Speech Engine page in Settings.
### Via the config file
The same options live in `~/.config/vocalinux/config.json`:
The same options live in `~/.config/voculinux/config.json`:
```json
{
@@ -120,7 +120,7 @@ The same options live in `~/.config/vocalinux/config.json`:
}
```
Restart Vocalinux after editing the file by hand.
Restart Voculinux after editing the file by hand.
FunASR/SenseVoice example:
@@ -201,7 +201,7 @@ en
```
For OpenAI-compatible FunASR/SenseVoice wrappers, extra metadata is allowed and
ignored by Vocalinux:
ignored by Voculinux:
```json
{
@@ -214,16 +214,16 @@ ignored by Vocalinux:
}
```
If `text` is not present, Vocalinux also accepts `transcript`, `transcription`,
If `text` is not present, Voculinux also accepts `transcript`, `transcription`,
or a `segments` list with per-segment `text` fields. If a SenseVoice wrapper
returns rich labels inline, for example `<|en|><|NEUTRAL|><|Speech|>hello`,
Vocalinux strips the leading labels before text injection.
Voculinux strips the leading labels before text injection.
Empty utterances should return `{"text": ""}`. HTTP 4xx/5xx responses are surfaced as transcription errors in the Vocalinux log.
Empty utterances should return `{"text": ""}`. HTTP 4xx/5xx responses are surfaced as transcription errors in the Voculinux log.
### Language handling
- Vocalinux's UI language `auto` is sent as **no `language` field** (server auto-detects).
- Voculinux's UI language `auto` is sent as **no `language` field** (server auto-detects).
- `en-us` is normalised to `en`.
- Anything else is forwarded verbatim.
@@ -273,10 +273,10 @@ compatible response shapes above.
| First transcription is slow | Cold model load on the server | Warm the server before dictating, or increase the client timeout server-side |
| Garbled text in foreign language | Wrong `language` setting | Set the language explicitly in Settings instead of `auto` |
Logs live at `~/.local/share/vocalinux/vocalinux.log` (or wherever your `XDG_DATA_HOME` points). Look for lines tagged `Remote API` for client-side detail.
Logs live at `~/.local/share/voculinux/voculinux.log` (or wherever your `XDG_DATA_HOME` points). Look for lines tagged `Remote API` for client-side detail.
## Security notes
- The API key is stored in plain JSON in `~/.config/vocalinux/config.json`. Treat that file the same way you treat any other secret on disk.
- The API key is stored in plain JSON in `~/.config/voculinux/config.json`. Treat that file the same way you treat any other secret on disk.
- Audio is sent as raw WAV. Anyone on the wire can hear it, so use HTTPS outside a fully trusted network.
- Vocalinux does **not** validate TLS certificate pins; standard system trust is used. Self-signed certs require importing the CA into your system trust store.
- Voculinux does **not** validate TLS certificate pins; standard system trust is used. Self-signed certs require importing the CA into your system trust store.
+55 -55
View File
@@ -1,6 +1,6 @@
# Installation guide
How to install Vocalinux on Linux. Short overview: [project README](../README.md).
How to install Voculinux on Linux. Short overview: [project README](../README.md).
| Path | When to use |
|------|-------------|
@@ -75,7 +75,7 @@ Useful flags: `--tag=TAG`, `--skip-models`, `--rebuild-whispercpp`, `--no-rebuil
1. Detects the distribution and installs system packages
2. Creates a Python venv from the system interpreter with `--system-site-packages` (for distro GTK / PyGObject)
3. Installs Vocalinux and the chosen speech engine
3. Installs Voculinux and the chosen speech engine
4. Optionally installs neural VAD (`onnxruntime`)
5. Downloads a default speech model (checksum-verified)
6. Installs icons, desktop entry, and `~/.local/bin` wrappers
@@ -85,8 +85,8 @@ Useful flags: `--tag=TAG`, `--skip-models`, `--rebuild-whispercpp`, `--no-rebuil
From [GitHub Releases](https://github.com/VocaHQ/vocalinux/releases):
```bash
chmod +x Vocalinux-*-x86_64.AppImage # or aarch64
./Vocalinux-*-x86_64.AppImage
chmod +x Voculinux-*-x86_64.AppImage # or aarch64
./Voculinux-*-x86_64.AppImage
```
Built against glibc 2.35, so it starts on Debian 12+, Ubuntu 22.04+, Fedora 36+, Arch, and Tumbleweed. Older bases (RHEL 9, Debian 11, Ubuntu 20.04) are below that AppImage floor. The installer and PyPI package still require a distro that ships Python 3.11+, so they are not a workaround for Debian 11 or Ubuntu 20.04.
@@ -99,13 +99,13 @@ From [GitHub Releases](https://github.com/VocaHQ/vocalinux/releases), pick the f
```bash
# Debian / Ubuntu (amd64; arm64 files are attached too)
sudo apt install ./vocalinux_*_amd64.deb
sudo apt install ./voculinux_*_amd64.deb
# Fedora (x86_64; aarch64 files are attached too)
sudo dnf install ./vocalinux-*.x86_64.rpm
sudo dnf install ./voculinux-*.x86_64.rpm
```
These are thin packages: Python, GTK, PyGObject and the AppIndicator typelib come from the distribution, and `apt`/`dnf` resolves them. `xdotool`, `wtype`, `ydotool`, the clipboard tools and IBus are `Recommends`, matching the optional feature set of the other paths. Only `pywhispercpp` and `pynput` are vendored inside the package — `pywhispercpp` is packaged by neither distro and `pynput` is missing on Fedora. They land under `/usr/lib/vocalinux/vendor`, on `sys.path` via the `vocalinux` launcher.
These are thin packages: Python, GTK, PyGObject and the AppIndicator typelib come from the distribution, and `apt`/`dnf` resolves them. `xdotool`, `wtype`, `ydotool`, the clipboard tools and IBus are `Recommends`, matching the optional feature set of the other paths. Only `pywhispercpp` and `pynput` are vendored inside the package — `pywhispercpp` is packaged by neither distro and `pynput` is missing on Fedora. They land under `/usr/lib/voculinux/vendor`, on `sys.path` via the `voculinux` launcher.
The `.deb` needs a distro that ships Python 3.11+: Debian 12+ and Ubuntu 24.04+ (Ubuntu 22.04 ships 3.10). whisper.cpp runs on CPU in these packages — the PyPI wheel, not the Vulkan build the AppImage carries. There is no auto-update: a new release is a new package install. A PPA and a COPR are not published yet.
@@ -120,7 +120,7 @@ Joining `input` grants read access to every keyboard and pointer device — X11
## Arch Linux (AUR)
```bash
yay -S vocalinux
yay -S voculinux
```
See [AUR.md](AUR.md).
@@ -130,21 +130,21 @@ See [AUR.md](AUR.md).
Install and auto-update via the self-hosted VocaHQ remote (`flatpak update` picks up each release):
```bash
flatpak install https://vocahq.github.io/vocalinux-flatpak/com.vocalinux.Vocalinux.flatpakref
flatpak install https://vocahq.github.io/voculinux-flatpak/com.voculinux.Voculinux.flatpakref
```
The `.flatpakref` adds the `vocahq` remote and resolves the GNOME runtime through Flathub. Manually instead:
```bash
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
flatpak remote-add --if-not-exists vocahq https://vocahq.github.io/vocalinux-flatpak/vocahq.flatpakrepo
flatpak install vocahq com.vocalinux.Vocalinux
flatpak remote-add --if-not-exists vocahq https://vocahq.github.io/voculinux-flatpak/vocahq.flatpakrepo
flatpak install vocahq com.voculinux.Voculinux
```
Or sideload a GitHub Release bundle (`Vocalinux-<version>-x86_64.flatpak` or `-aarch64.flatpak`) after the Flathub GNOME runtime is present — bundles do not auto-update:
Or sideload a GitHub Release bundle (`Voculinux-<version>-x86_64.flatpak` or `-aarch64.flatpak`) after the Flathub GNOME runtime is present — bundles do not auto-update:
```bash
flatpak install --user ./Vocalinux-<version>-x86_64.flatpak
flatpak install --user ./Voculinux-<version>-x86_64.flatpak
```
Local build (contributors):
@@ -152,8 +152,8 @@ Local build (contributors):
```bash
flatpak install flathub org.gnome.Platform//50 org.gnome.Sdk//50
flatpak-builder --user --install --force-clean build-dir \
packaging/flatpak/com.vocalinux.Vocalinux.yml
flatpak run com.vocalinux.Vocalinux
packaging/flatpak/com.voculinux.Voculinux.yml
flatpak run com.voculinux.Voculinux
```
Whisper.cpp + Vulkan. It is **not on Flathub** (submission [flathub#9368](https://github.com/flathub/flathub/pull/9368) closed 2026-07-23 on policy grounds). Details: [packaging/flatpak/README.md](../packaging/flatpak/README.md).
@@ -168,7 +168,7 @@ Desktop shortcuts only toggle dictation, so they cannot support push-to-talk.
## Snap (Ubuntu Snap Store)
Listing: [snapcraft.io/vocalinux](https://snapcraft.io/vocalinux) (issue [#48](https://github.com/VocaHQ/vocalinux/issues/48)). Recipe: `snap/snapcraft.yaml`. Tagged `v*` releases attach `vocalinux_<version>_amd64.snap` to the GitHub Release and try Snap Store `edge` and `candidate` when credentials are set. `stable` is promoted from `candidate` after QA.
Listing: [snapcraft.io/voculinux](https://snapcraft.io/voculinux) (issue [#48](https://github.com/VocaHQ/vocalinux/issues/48)). Recipe: `snap/snapcraft.yaml`. Tagged `v*` releases attach `voculinux_<version>_amd64.snap` to the GitHub Release and try Snap Store `edge` and `candidate` when credentials are set. `stable` is promoted from `candidate` after QA.
Build inputs, the PR/release artifact gate, and its verification limits are
documented in [SNAP.md](SNAP.md).
@@ -176,10 +176,10 @@ documented in [SNAP.md](SNAP.md).
Store install, once Canonical lists the revision:
```bash
sudo snap install vocalinux --edge
sudo snap connect vocalinux:audio-record # if mic is not auto-connected
sudo snap connect vocalinux:raw-input # global keyboard shortcuts (evdev)
sudo snap connect vocalinux:hardware-observe # list keyboards (/proc/bus/input/devices)
sudo snap install voculinux --edge
sudo snap connect voculinux:audio-record # if mic is not auto-connected
sudo snap connect voculinux:raw-input # global keyboard shortcuts (evdev)
sudo snap connect voculinux:hardware-observe # list keyboards (/proc/bus/input/devices)
```
Native Wayland typing uses the RemoteDesktop portal: the compositor asks once on first dictation, nothing to connect. The recipe ships **no `uinput` plug** and no ydotool; the Store denied the super-privileged grant ([the request thread](https://forum.snapcraft.io/t/53528)), which held the 0.17.0+ revisions and left **v0.16.2 (rev 7)** on edge. On KDE Plasma, KWin's portal can mistype letter case ([KDE bug 489021](https://bugs.kde.org/show_bug.cgi?id=489021)); set Virtual Keyboard to "IBus Wayland" so dictation types correctly.
@@ -189,14 +189,14 @@ Under strict confinement the snap reaches audio through the PulseAudio/PipeWire
GitHub `.snap` files through v0.18.2 declare `uinput`, so KDE users who want ydotool can sideload that build and connect the plug manually:
```bash
sudo snap install --dangerous ./vocalinux_0.18.2_amd64.snap
sudo snap connect vocalinux:audio-record
sudo snap connect vocalinux:raw-input
sudo snap connect vocalinux:hardware-observe
sudo snap connect vocalinux:uinput # only in the v0.18.x sideload; the recipe no longer ships it
sudo snap install --dangerous ./voculinux_0.18.2_amd64.snap
sudo snap connect voculinux:audio-record
sudo snap connect voculinux:raw-input
sudo snap connect voculinux:hardware-observe
sudo snap connect voculinux:uinput # only in the v0.18.x sideload; the recipe no longer ships it
```
`--dangerous` is required because this file is not a Store revision and will not refresh from the Store; once the Store carries a newer revision, `sudo snap install vocalinux --edge` (or `snap refresh`) replaces it.
`--dangerous` is required because this file is not a Store revision and will not refresh from the Store; once the Store carries a newer revision, `sudo snap install voculinux --edge` (or `snap refresh`) replaces it.
## Nix / NixOS
@@ -207,13 +207,13 @@ nix run github:VocaHQ/vocalinux # try it
nix profile install github:VocaHQ/vocalinux
```
On NixOS, `vocalinux.nixosModules.vocalinux` provides `programs.vocalinux.enable`, which installs the package and enables `hardware.uinput`. Add each dictating user to `input` and `uinput` for Wayland shortcuts and ydotool typing. Home Manager users get `vocalinux.homeManagerModules.vocalinux` with the same `programs.vocalinux` options — device permissions stay on the system side. Usage snippets and scope notes: [packaging/nix/README.md](../packaging/nix/README.md).
On NixOS, `voculinux.nixosModules.voculinux` provides `programs.voculinux.enable`, which installs the package and enables `hardware.uinput`. Add each dictating user to `input` and `uinput` for Wayland shortcuts and ydotool typing. Home Manager users get `voculinux.homeManagerModules.voculinux` with the same `programs.voculinux` options — device permissions stay on the system side. Usage snippets and scope notes: [packaging/nix/README.md](../packaging/nix/README.md).
## From source
```bash
git clone https://github.com/VocaHQ/vocalinux.git
cd vocalinux
cd voculinux
./install.sh
```
@@ -228,18 +228,18 @@ cd vocalinux
| **Disk** | ~200MB with default whisper.cpp model |
| **RAM** | 4GB minimum; 8GB comfortable |
The distro must ship Python 3.11+ because Vocalinux uses distro PyGObject (`python3-gi`). Ubuntu 22.04 (Python 3.10) and Debian 11 (3.9) are below that floor. Distro matrix: [DISTRO_COMPATIBILITY.md](DISTRO_COMPATIBILITY.md).
The distro must ship Python 3.11+ because Voculinux uses distro PyGObject (`python3-gi`). Ubuntu 22.04 (Python 3.10) and Debian 11 (3.9) are below that floor. Distro matrix: [DISTRO_COMPATIBILITY.md](DISTRO_COMPATIBILITY.md).
### GPU (optional)
whisper.cpp uses Vulkan when available (AMD, Intel, NVIDIA). Check with `vulkaninfo --summary`.
## Running Vocalinux
## Running Voculinux
```bash
vocalinux # if ~/.local/bin is on PATH
~/.local/share/vocalinux/venv/bin/vocalinux # direct
source venv/bin/activate && vocalinux # source checkout
voculinux # if ~/.local/bin is on PATH
~/.local/share/voculinux/venv/bin/voculinux # direct
source venv/bin/activate && voculinux # source checkout
```
Or launch from the application menu.
@@ -247,19 +247,19 @@ Or launch from the application menu.
### CLI
```bash
vocalinux --help
vocalinux --version
vocalinux --debug
vocalinux --engine whisper_cpp
vocalinux --engine whisper
vocalinux --engine vosk
vocalinux --engine parakeet
vocalinux --engine remote_api
vocalinux --model tiny
vocalinux --model medium.en-q5_0
vocalinux --model large-v3-turbo
vocalinux --wayland
vocalinux --start-minimized
voculinux --help
voculinux --version
voculinux --debug
voculinux --engine whisper_cpp
voculinux --engine whisper
voculinux --engine vosk
voculinux --engine parakeet
voculinux --engine remote_api
voculinux --model tiny
voculinux --model medium.en-q5_0
voculinux --model large-v3-turbo
voculinux --wayland
voculinux --start-minimized
```
## Autostart
@@ -270,8 +270,8 @@ vocalinux --start-minimized
| Directory | Purpose |
|-----------|---------|
| `~/.config/vocalinux/` | Configuration |
| `~/.local/share/vocalinux/` | Data and speech models |
| `~/.config/voculinux/` | Configuration |
| `~/.local/share/voculinux/` | Data and speech models |
| `~/.local/share/applications/` | Desktop entry |
| `~/.local/share/icons/hicolor/scalable/apps/` | Icons |
@@ -296,11 +296,11 @@ Reuse an existing `pywhispercpp` build:
./install.sh --auto --rebuild-whispercpp # force rebuild
```
Switch engines in Settings → Speech Model (Advanced), or edit `~/.config/vocalinux/config.json` (`engine`: `whisper_cpp` | `whisper` | `vosk` | `parakeet` | `remote_api`).
Switch engines in Settings → Speech Model (Advanced), or edit `~/.config/voculinux/config.json` (`engine`: `whisper_cpp` | `whisper` | `vosk` | `parakeet` | `remote_api`).
## Uninstall
From a source checkout, `./uninstall.sh` removes the install and that checkout's `venv/`, `build/`, `dist/`, and Python bytecode. `--keep-config` and `--keep-data` leave `~/.config/vocalinux` and `~/.local/share/vocalinux` in place.
From a source checkout, `./uninstall.sh` removes the install and that checkout's `venv/`, `build/`, `dist/`, and Python bytecode. `--keep-config` and `--keep-data` leave `~/.config/voculinux` and `~/.local/share/voculinux` in place.
```bash
./uninstall.sh
@@ -315,15 +315,15 @@ curl -fsSL https://raw.githubusercontent.com/VocaHQ/vocalinux/main/uninstall.sh
bash /tmp/vul.sh
```
That removes Vocalinux from your home directory (config, data, launchers, desktop entry, icons). It does not delete `venv/`, `build/`, `dist/`, or `.pyc` files in the directory where you ran it.
That removes Voculinux from your home directory (config, data, launchers, desktop entry, icons). It does not delete `venv/`, `build/`, `dist/`, or `.pyc` files in the directory where you ran it.
From the source checkout, the equivalent by hand:
```bash
rm -rf venv ~/.config/vocalinux ~/.local/share/vocalinux
rm -f activate-vocalinux.sh
rm -f ~/.local/share/applications/vocalinux.desktop
rm -f ~/.local/share/icons/hicolor/scalable/apps/vocalinux*.svg
rm -rf venv ~/.config/voculinux ~/.local/share/voculinux
rm -f activate-voculinux.sh
rm -f ~/.local/share/applications/voculinux.desktop
rm -f ~/.local/share/icons/hicolor/scalable/apps/voculinux*.svg
gtk-update-icon-cache -f -t ~/.local/share/icons/hicolor
```
+19 -19
View File
@@ -12,7 +12,7 @@ Related: [DISTRO_COMPATIBILITY.md](DISTRO_COMPATIBILITY.md), [TROUBLESHOOTING.md
## System packages by distribution
Install desktop/system dependencies **before** creating a venv or running `pip install vocalinux`. Pip cannot install GTK typelibs, AppIndicator, PortAudio, or text-injection tools.
Install desktop/system dependencies **before** creating a venv or running `pip install voculinux`. Pip cannot install GTK typelibs, AppIndicator, PortAudio, or text-injection tools.
Debian 11 and earlier are unsupported; the Debian instructions start at Debian
12, which is the oldest release with the required Python 3.11.
@@ -84,7 +84,7 @@ sudo dnf install -y \
### Arch Linux
Prefer the AUR package (`yay -S vocalinux`). Manual packages:
Prefer the AUR package (`yay -S voculinux`). Manual packages:
```bash
sudo pacman -S --needed \
@@ -125,7 +125,7 @@ Gentoo, Alpine, Void, Solus, Mageia: [DISTRO_COMPATIBILITY.md](DISTRO_COMPATIBIL
Use the **system** Python (`/usr/bin/python3`). Distro PyGObject (`gi`) is compiled for that interpreter only, so a venv from pyenv/conda/uv cannot import it even with `--system-site-packages`.
```bash
cd vocalinux
cd voculinux
/usr/bin/python3 -m venv venv --system-site-packages
source venv/bin/activate
pip install --upgrade pip setuptools wheel
@@ -141,14 +141,14 @@ pip install -e ".[dev,vad]" # development
### Desktop integration
```bash
mkdir -p ~/.config/vocalinux \
~/.local/share/vocalinux/models \
mkdir -p ~/.config/voculinux \
~/.local/share/voculinux/models \
~/.local/share/applications \
~/.local/share/icons/hicolor/scalable/apps
cp vocalinux.desktop ~/.local/share/applications/
VENV_PATH=$(realpath venv/bin/vocalinux)
sed -i "s|^Exec=vocalinux|Exec=$VENV_PATH|" ~/.local/share/applications/vocalinux.desktop
cp voculinux.desktop ~/.local/share/applications/
VENV_PATH=$(realpath venv/bin/voculinux)
sed -i "s|^Exec=voculinux|Exec=$VENV_PATH|" ~/.local/share/applications/voculinux.desktop
cp resources/icons/scalable/*.svg ~/.local/share/icons/hicolor/scalable/apps/
gtk-update-icon-cache -f -t ~/.local/share/icons/hicolor
@@ -159,14 +159,14 @@ gtk-update-icon-cache -f -t ~/.local/share/icons/hicolor
Same system packages as above, then:
```bash
python3 -m venv ~/.local/share/vocalinux-pypi/venv --system-site-packages
source ~/.local/share/vocalinux-pypi/venv/bin/activate
python3 -m venv ~/.local/share/voculinux-pypi/venv --system-site-packages
source ~/.local/share/voculinux-pypi/venv/bin/activate
pip install --upgrade pip setuptools wheel
pip install vocalinux
# vosk engine: pip install "vocalinux[vosk]"
# faster-whisper: pip install "vocalinux[faster_whisper]"
# parakeet engine: pip install "vocalinux[parakeet]"
vocalinux
pip install voculinux
# vosk engine: pip install "voculinux[vosk]"
# faster-whisper: pip install "voculinux[faster_whisper]"
# parakeet engine: pip install "voculinux[parakeet]"
voculinux
```
`--system-site-packages` lets the venv use distro GTK bindings (`python3-gi`). Building PyGObject from pip is often painful on Ubuntu/Debian.
@@ -177,18 +177,18 @@ If the app starts but no speech model is present, open Settings and download a m
```bash
# After system packages are installed:
pipx install vocalinux
vocalinux
pipx install voculinux
voculinux
```
pipx still cannot install system desktop libraries. Install those first with your package manager.
## Why system packages are required
Vocalinux uses GTK3, AppIndicator/Ayatana, PortAudio, and tools such as `xdotool`, `wtype`, and clipboard utilities. Those come from the distro. PyPI only supplies Python packages and wheels.
Voculinux uses GTK3, AppIndicator/Ayatana, PortAudio, and tools such as `xdotool`, `wtype`, and clipboard utilities. Those come from the distro. PyPI only supplies Python packages and wheels.
## After install
- Run: [INSTALL.md](INSTALL.md#running-vocalinux)
- Run: [INSTALL.md](INSTALL.md#running-voculinux)
- Engines and models: [USER_GUIDE.md](USER_GUIDE.md)
- Failures: [TROUBLESHOOTING.md](TROUBLESHOOTING.md)
+4 -4
View File
@@ -1,6 +1,6 @@
# Choosing a speech model
Vocalinux never downloads a speech model on its own. Changing the model pickers in
Voculinux never downloads a speech model on its own. Changing the model pickers in
Settings → Speech Model only selects a model. If that model is not on disk yet, the
info card shows its download size and a **Download** button, and the transfer starts
only after you confirm it. Cancelling the download, or declining the confirmation,
@@ -43,7 +43,7 @@ more accurate for English.
| Large v3 Turbo | 1.6 GB | 874 MB | 574 MB (q5_0) | 809M |
| Large (v3) | 2.9 GB | | 1.1 GB (q5_0) | 1550M |
Sizes are the catalog values Vocalinux shows before a download; the file on disk can
Sizes are the catalog values Voculinux shows before a download; the file on disk can
differ slightly.
If you already have a quantized model of the size you want (for example Small Q8_0),
@@ -57,5 +57,5 @@ there is no reason to download the full model of the same size.
- **Parakeet**: one model of about 640 MB.
- **Remote API**: transcription runs on your server, nothing is downloaded locally.
Models are stored under `~/.local/share/vocalinux/models/` by default. Deleting a file there
removes the model; Vocalinux will show it as not downloaded again.
Models are stored under `~/.local/share/voculinux/models/` by default. Deleting a file there
removes the model; Voculinux will show it as not downloaded again.
+3 -3
View File
@@ -19,7 +19,7 @@ no CUDA toolkit installed (Vulkan then CPU backend order).
`small.en` (floor, by language).
- Isolated XDG directories so the pass never touches a live install:
point `XDG_CONFIG_HOME`, `XDG_DATA_HOME`, `XDG_STATE_HOME` at scratch
roots and link the verified models under `<data>/vocalinux/models/`.
roots and link the verified models under `<data>/voculinux/models/`.
- Seed `config.json` from the app's own `DEFAULT_CONFIG`: engine
`whisper_cpp`, the rung under test, keep-alive enabled with the
minimum 60 s timeout, `first_run` false, update checks off.
@@ -36,8 +36,8 @@ with the installed build's interpreter.
`reason=idle_keepalive`). RSS does not reflect the unload (freed
native pages stay mapped); VRAM-used is the state signal.
2. **Wake latency, toggle to capture start.** Drive starts over D-Bus
(`busctl --user call com.vocalinux.Vocalinux
/com/vocalinux/Vocalinux com.vocalinux.Vocalinux Toggle`; the
(`busctl --user call com.voculinux.Voculinux
/com/voculinux/Voculinux com.voculinux.Voculinux Toggle`; the
`--toggle` client also works but spawns the full app stack).
Parse repeated runs with `parse-log --log`: each `Toggle requested
in state IDLE` pairs with the next `Opened capture stream`. Report
+2 -2
View File
@@ -1,6 +1,6 @@
# Documentation
User and maintainer documentation for Vocalinux.
User and maintainer documentation for Voculinux.
| Document | Audience | Description |
|----------|----------|-------------|
@@ -32,4 +32,4 @@ Project root:
Website product and design notes live under [`web/`](../web/) (`PRODUCT.md`, `DESIGN.md`, `README.md`). Flatpak packaging: [`packaging/flatpak/README.md`](../packaging/flatpak/README.md).
Website: [vocalinux.com](https://vocalinux.com)
Website: [voculinux.com](https://voculinux.com)
+17 -17
View File
@@ -1,10 +1,10 @@
# Vocalinux Release Process
# Voculinux Release Process
This document outlines the step-by-step process for creating a new release of Vocalinux.
This document outlines the step-by-step process for creating a new release of Voculinux.
## Overview
Vocalinux uses [Semantic Versioning](https://semver.org/) with pre-release suffixes:
Voculinux uses [Semantic Versioning](https://semver.org/) with pre-release suffixes:
- **Alpha**: Early testing phase (e.g., `0.4.1-alpha`)
- **Beta**: Feature-complete, testing phase (e.g., `0.5.0-beta`)
- **RC** (Release Candidate): Final testing before stable (e.g., `0.5.0-rc1`)
@@ -19,13 +19,13 @@ in the corresponding job.
`publish-pypi` authenticates with a short-lived OIDC token instead of a stored API
token, so there is no `PYPI_API_TOKEN` secret to leak or rotate. It only works once
PyPI knows about this workflow. On https://pypi.org/manage/project/vocalinux/settings/publishing/
PyPI knows about this workflow. On https://pypi.org/manage/project/voculinux/settings/publishing/
add a GitHub publisher:
| field | value |
|---|---|
| Owner | `VocaHQ` |
| Repository | `vocalinux` |
| Repository | `voculinux` |
| Workflow name | `release.yml` |
| Environment | `pypi` |
@@ -144,7 +144,7 @@ AUR push, but does not unpublish GitHub/PyPI artifacts already released. It is
separate from PR/local `--local-unattested` fixtures, which exercise the same
preparation/build path but are never used for publication. See [AUR.md](AUR.md)
for the trust model and the existing AUR-provider smoke-test limitations.
`vocalinux-bin` publication waits only for release creation and both AppImages;
`voculinux-bin` publication waits only for release creation and both AppImages;
source-gate failures or unrelated checksum producers do not block it.
## Detailed Release Steps
@@ -199,9 +199,9 @@ When shipping bug fixes only (PATCH bump, same MINOR):
- **README / `docs/UPDATE.md` "What's New"** keeps the **minor-series feature list** (everything introduced in that 0.Y line) and adds a short **Bug fixes in this patch** subsection for the delta only. Do not make the marketing highlight table look featureless because this tag only contains fixes.
- **Website changelog** (`web/src/app/changelog/page.tsx`) may list only the delta for the new entry; older entries stay historical.
- **AppStream** (`packaging/flatpak/com.vocalinux.Vocalinux.metainfo.xml`): add a short `<release>` note for the patch delta only; leave the long product feature `<ul>` as series/product-level.
- **AppStream** (`packaging/flatpak/com.voculinux.Voculinux.metainfo.xml`): add a short `<release>` note for the patch delta only; leave the long product feature `<ul>` as series/product-level.
- **SECURITY.md** supported versions table usually stays on the minor line (`0.14.x`) without a row per patch.
- **AUR source PKGBUILD**: the release gate prepares `pkgver`, `_tag`, the normalized `_version`, and the canonical sdist digest, then tests that exact file. Do not introduce `SKIP` or rehash it during publication. The separate `vocalinux-bin` path still pins both AppImage digests before its own publication.
- **AUR source PKGBUILD**: the release gate prepares `pkgver`, `_tag`, the normalized `_version`, and the canonical sdist digest, then tests that exact file. Do not introduce `SKIP` or rehash it during publication. The separate `voculinux-bin` path still pins both AppImage digests before its own publication.
- **Dates**: patch release dates must not predate the previous release in changelog / AppStream / version history.
### GitHub Release Notes Writing Rules
@@ -216,7 +216,7 @@ Use these rules for every GitHub Release body (and for the draft pasted into the
#### Required structure
1. `# Vocalinux vX.Y.Z` title
1. `# Voculinux vX.Y.Z` title
2. One to three plain sentences: what this release is for (no hype)
3. `## Highlights` - markdown table, about 4-8 rows
4. `## New Features` - bullets with PR + author; include issue closes when real
@@ -334,7 +334,7 @@ Add new release entry to the `releases` array at the top of the file.
```json
{
"name": "vocalinux-website",
"name": "voculinux-website",
"version": "0.5.0"
}
```
@@ -369,7 +369,7 @@ bash -n install.sh
### Upstream Fix Intake (Cherry-Pick Policy)
Upstream Vocalinux fixes enter this fork only as hand cherry-picks: taken at
Upstream Voculinux fixes enter this fork only as hand cherry-picks: taken at
defined sync points, never as continuous tracking and never as wholesale
merges. Like every other change, each port goes through the pull request flow
with the standard test, lint, and type gates. Never land one as a direct or
@@ -390,7 +390,7 @@ worktree per branch, every change via a pull request, never commit on `main`
renames on top. Conflicts concentrate at the renamed user-visible surfaces
(application name, entry points, desktop and D-Bus identity, configuration
and data directories, package, website) precisely because the internal
Python module name stays `vocalinux` as a retained internal name — that
Python module name stays `voculinux` as a retained internal name — that
split is what keeps hand cherry-picks nearly conflict-free everywhere else.
Upstream URLs and changelog history stay untouched for provenance.
- **What qualifies.** Fixes and documentation that changes user instructions
@@ -448,7 +448,7 @@ git checkout main
git pull origin main
# Create annotated tag
git tag -a v0.5.0-beta -m "Vocalinux Beta Release 0.5.0
git tag -a v0.5.0-beta -m "Voculinux Beta Release 0.5.0
Key changes since 0.4.1-alpha:
- Feature 1
@@ -481,7 +481,7 @@ After pushing the tag, the GitHub Actions workflow will automatically:
(stable tags only, once the GitHub Release exists, when
`FLATPAK_GPG_PRIVATE_KEY` + `FLATPAK_REPO_TOKEN` are configured — see
docs/FLATPAK_REMOTE.md)
8. Deploy the website to vocalinux.com
8. Deploy the website to voculinux.com
9. Build the amd64 snap from locked Python exports and run the installed-artifact
gate described in [SNAP.md](SNAP.md), then attach it to the GitHub Release and
try Snap Store
@@ -511,9 +511,9 @@ Monitor at: https://github.com/VocaHQ/vocalinux/actions
- [ ] Verify provenance: `gh attestation verify <artifact> --repo VocaHQ/vocalinux`
- [ ] Verify PyPI package was published (if applicable), and that its wheel sha256
matches the line for that wheel in `SHA256SUMS`
- [ ] Verify website was deployed (check vocalinux.com)
- [ ] Verify website was deployed (check voculinux.com)
- [ ] If the Flatpak remote is configured, verify it picked up the tag:
`flatpak remote-info vocahq com.vocalinux.Vocalinux` (docs/FLATPAK_REMOTE.md)
`flatpak remote-info vocahq com.voculinux.Voculinux` (docs/FLATPAK_REMOTE.md)
- [ ] Announce on social media/communities
- [ ] Update any pinned issues or discussions
@@ -562,7 +562,7 @@ git push origin v0.5.1-beta
| 0.14.1 | 2026-07-17 | Stable | Flatpak packaging, AUR package, layout-aware hotkeys, installer/text-injection fixes |
| 0.14.2 | 2026-07-17 | Stable | IBus engine launch + FocusIn gate; settings tabs scroll to fit monitor |
| 0.15.0 | 2026-07-28 | Stable | Searchable settings + sidebar dictation footer, AppImage, expanded languages, dictation polish, auto-pause/keepalive, Vulkan device selection, ibus-wayland, Bluetooth mic + shortcut UI fixes |
| 0.16.0 | 2026-08-23 | Stable | Update checker + tray notify, Right Alt PTT default (new installs), searchable language list, delete unused models, Voca tone picker (family preview WAVs), About page, AGPL-3.0, family mic icons, installer/just/uv pinning, Test Dictation missing-model message, IBus/audio/clipboard/GPU/AppImage reliability, vocalinux.com family workbench restyle |
| 0.16.0 | 2026-08-23 | Stable | Update checker + tray notify, Right Alt PTT default (new installs), searchable language list, delete unused models, Voca tone picker (family preview WAVs), About page, AGPL-3.0, family mic icons, installer/just/uv pinning, Test Dictation missing-model message, IBus/audio/clipboard/GPU/AppImage reliability, voculinux.com family workbench restyle |
| 0.17.0 | 2026-09-16 | Stable | Faster Whisper + Parakeet engines, Speech Model simple setup, first-run system language, Snap with ydotool/uinput, Flatpak bundles on the GitHub Release, XWayland/layout paste and settings/audio fixes |
| 0.18.0 | 2026-10-02 | Stable | Dictation Pad, evdev hotkey suppression, PipeWire capture + system audio, RemoteDesktop portal injection, per-language shortcuts + tray history, TinyDiarize file transcription, D-Bus activation, custom dictionary, postprocessing hook, floating overlay, audio ducking, AUR -bin + self-hosted Flatpak remote + snap-promote |
| 0.18.1 | 2026-10-08 | Stable | Settings Proxy page, opt-in JSONL transcript persistence, .deb/.rpm release packages, slimmer tray menu, dictation-pad Wayland ghost fix, evdev keyboard-discovery tightening, KWin 6 case fix, staged model picker |
+4 -4
View File
@@ -30,7 +30,7 @@ packages over incidental copies in the GNOME platform.
The build audits build-tool and installed runtime versions against the active
export pins and records expected runtime versions and both export digests in
`usr/share/vocalinux/python-inputs.json` inside the snap. Missing or wrong-version
`usr/share/voculinux/python-inputs.json` inside the snap. Missing or wrong-version
build tools fail the build. For the packaged runtime, extra and duplicate
Python distributions are rejected as well.
@@ -49,15 +49,15 @@ snapcraft pack
On a **disposable Ubuntu host with snapd**, inspect the resulting artifact:
```bash
bash snap/local/smoke-test.sh ./vocalinux_<version>_amd64.snap
bash snap/local/smoke-test.sh ./voculinux_<version>_amd64.snap
```
Replace `<version>` with the version that was built. The script refuses to overwrite an
existing Vocalinux snap. It installs the supplied file with `--dangerous`,
existing Voculinux snap. It installs the supplied file with `--dangerous`,
runs the actual application launcher with `--version`, then enters the GNOME
command-chain environment to audit Python versions and import the native,
GTK, recognition and text-injection modules. It leaves the installation in
place for inspection; use a disposable host, not your normal Vocalinux install.
place for inspection; use a disposable host, not your normal Voculinux install.
`unified-pipeline.yml` builds and runs this gate on relevant Python/Snap PRs and
main pushes, including recipe-only changes. `release.yml` runs it before the
+18 -18
View File
@@ -5,36 +5,36 @@ Common install and runtime problems. Install overview: [INSTALL.md](INSTALL.md).
Always try once with debug logs:
```bash
vocalinux --debug
voculinux --debug
```
## Command not found: `vocalinux`
## Command not found: `voculinux`
```bash
# Official install wrappers
export PATH="$HOME/.local/bin:$PATH"
vocalinux
voculinux
# Or run the venv binary
~/.local/share/vocalinux/venv/bin/vocalinux
~/.local/share/voculinux/venv/bin/voculinux
# Source checkout
source venv/bin/activate
vocalinux
voculinux
```
## No audio / microphone not working
1. Check system sound settings and mute state
2. List capture devices: `arecord -l`
3. Run `vocalinux --debug` and confirm the selected device
4. Reset a bad device index: set `audio.device_index` to `null` in `~/.config/vocalinux/config.json`
3. Run `voculinux --debug` and confirm the selected device
4. Reset a bad device index: set `audio.device_index` to `null` in `~/.config/voculinux/config.json`
5. Bluetooth mics: try a wired device to isolate SCO capture issues
### Microphone Stalled
A **Microphone Stalled** notification means the selected input stopped delivering
audio. Vocalinux stops the failed dictation attempt.
audio. Voculinux stops the failed dictation attempt.
Open **Settings → Audio**. Use **Microphone Test → Test** to record two seconds and
check the audio level, or select a different **Input Device**, then retry
@@ -75,7 +75,7 @@ Refresh icons:
```bash
gtk-update-icon-cache -f -t ~/.local/share/icons/hicolor
vocalinux --debug
voculinux --debug
```
## Text not injected into apps
@@ -95,7 +95,7 @@ wtype "hello"
printf "bonjour" | xsel --clipboard --input
```
**KDE Plasma Wayland:** `wtype` may fail if the compositor does not expose a virtual keyboard to normal clients. Prefer **System Settings → Keyboard → Virtual Keyboard → IBus Wayland**, then restart Vocalinux (or log out/in).
**KDE Plasma Wayland:** `wtype` may fail if the compositor does not expose a virtual keyboard to normal clients. Prefer **System Settings → Keyboard → Virtual Keyboard → IBus Wayland**, then restart Voculinux (or log out/in).
Install IBus if needed:
@@ -115,8 +115,8 @@ Compositor-specific notes: [DISTRO_COMPATIBILITY.md](DISTRO_COMPATIBILITY.md).
Models download on first use. Manual VOSK example:
```bash
mkdir -p ~/.local/share/vocalinux/models
cd ~/.local/share/vocalinux/models
mkdir -p ~/.local/share/voculinux/models
cd ~/.local/share/voculinux/models
wget https://alphacephei.com/vosk/models/vosk-model-small-en-us-0.15.zip
unzip vosk-model-small-en-us-0.15.zip
```
@@ -128,23 +128,23 @@ whisper.cpp models are managed from Settings or first-run download.
```bash
# Unresolved libs
ldd $(find ~/.local/share/vocalinux/venv -name '*.so' -path '*/pywhispercpp*' 2>/dev/null | head -1) | grep 'not found'
ldd $(find ~/.local/share/voculinux/venv -name '*.so' -path '*/pywhispercpp*' 2>/dev/null | head -1) | grep 'not found'
# Rebuild whisper.cpp bindings via installer
./install.sh --auto --rebuild-whispercpp
# Or switch to VOSK temporarily
vocalinux --engine vosk
voculinux --engine vosk
```
## Old process still running after update
Stop via the tray, or use the lock-file PID (do **not** use `pkill -f vocalinux`; it can kill editors and shells):
Stop via the tray, or use the lock-file PID (do **not** use `pkill -f voculinux`; it can kill editors and shells):
```bash
kill "$(tr -d '[:space:]' < "${XDG_DATA_HOME:-$HOME/.local/share}/vocalinux/instance.lock")"
kill "$(tr -d '[:space:]' < "${XDG_DATA_HOME:-$HOME/.local/share}/vocalinux-ibus/engine.pid")"
vocalinux
kill "$(tr -d '[:space:]' < "${XDG_DATA_HOME:-$HOME/.local/share}/voculinux/instance.lock")"
kill "$(tr -d '[:space:]' < "${XDG_DATA_HOME:-$HOME/.local/share}/voculinux-ibus/engine.pid")"
voculinux
```
## Clean reinstall
+16 -16
View File
@@ -1,10 +1,10 @@
# Updating Vocalinux
# Updating Voculinux
How to upgrade an existing install, plus release notes for the current series.
## Quick update
Vocalinux checks GitHub Releases in the background about every six hours (and shortly after startup). When a newer build is on your selected channel, the tray menu gains an **Update Available...** entry and Settings -> About shows a green **New** badge; open that page for release notes and download links. Updates are not installed automatically. Re-run the installer (or your package manager) as below.
Voculinux checks GitHub Releases in the background about every six hours (and shortly after startup). When a newer build is on your selected channel, the tray menu gains an **Update Available...** entry and Settings -> About shows a green **New** badge; open that page for release notes and download links. Updates are not installed automatically. Re-run the installer (or your package manager) as below.
### Official installer
@@ -15,7 +15,7 @@ bash /tmp/vl.sh
The installer detects a running instance, updates in place, preserves configuration and models, and pulls new dependencies (including neural VAD when available).
On an existing install (a virtual environment plus `~/.config/vocalinux/config.json`), the installer reports the saved configuration and defaults to **Upgrade (keep current settings)**: the configured engine stays selected, `config.json` is never rewritten, the virtual environment is reused, downloaded models are kept, and pywhispercpp is rebuilt only when this release pins a new version or GPU support is missing. Pick the interactive or automatic modes instead if you want to reconfigure the install.
On an existing install (a virtual environment plus `~/.config/voculinux/config.json`), the installer reports the saved configuration and defaults to **Upgrade (keep current settings)**: the configured engine stays selected, `config.json` is never rewritten, the virtual environment is reused, downloaded models are kept, and pywhispercpp is rebuilt only when this release pins a new version or GPU support is missing. Pick the interactive or automatic modes instead if you want to reconfigure the install.
For a scripted, non-interactive upgrade:
@@ -28,7 +28,7 @@ bash /tmp/vl.sh --upgrade
### Installed from source
```bash
cd vocalinux
cd voculinux
git fetch origin
git checkout v0.18.5
./install.sh
@@ -37,7 +37,7 @@ git checkout v0.18.5
Latest development tree:
```bash
cd vocalinux
cd voculinux
git pull origin main
./install.sh
```
@@ -46,16 +46,16 @@ git pull origin main
| Method | Upgrade |
|--------|---------|
| AUR | `yay -S vocalinux` (or your AUR helper) |
| AUR | `yay -S voculinux` (or your AUR helper) |
| AppImage | Download the new file from [Releases](https://github.com/VocaHQ/vocalinux/releases) |
| Snap | Store: `sudo snap refresh vocalinux` (`--edge` until stable is promoted). The recipe ships no `uinput` plug (the Store denied the grant); Wayland typing uses the RemoteDesktop portal. The GitHub `vocalinux_0.18.2_amd64.snap` still declares `uinput` for KDE users who want ydotool (`sudo snap install --dangerous`, then `sudo snap connect vocalinux:uinput`). |
| Snap | Store: `sudo snap refresh voculinux` (`--edge` until stable is promoted). The recipe ships no `uinput` plug (the Store denied the grant); Wayland typing uses the RemoteDesktop portal. The GitHub `voculinux_0.18.2_amd64.snap` still declares `uinput` for KDE users who want ydotool (`sudo snap install --dangerous`, then `sudo snap connect voculinux:uinput`). |
| Flatpak (release bundle) | Install the new `.flatpak` from Releases; bundles do not auto-update |
| PyPI | Reinstall in the same venv after system packages are current |
### Check your version
```bash
vocalinux --version
voculinux --version
# or
python3 -c "import vocalinux; print(vocalinux.version.__version__)"
```
@@ -76,13 +76,13 @@ curl -fsSL https://raw.githubusercontent.com/VocaHQ/vocalinux/main/install.sh -o
bash /tmp/vl.sh
```
If an old process is stuck, stop via the tray or the PID in the instance lock file (do not use `pkill -f vocalinux`; it can kill unrelated processes):
If an old process is stuck, stop via the tray or the PID in the instance lock file (do not use `pkill -f voculinux`; it can kill unrelated processes):
```bash
kill "$(tr -d '[:space:]' < "${XDG_DATA_HOME:-$HOME/.local/share}/vocalinux/instance.lock")"
kill "$(tr -d '[:space:]' < "${XDG_DATA_HOME:-$HOME/.local/share}/voculinux/instance.lock")"
# If you use IBus injection:
kill "$(tr -d '[:space:]' < "${XDG_DATA_HOME:-$HOME/.local/share}/vocalinux-ibus/engine.pid")"
vocalinux
kill "$(tr -d '[:space:]' < "${XDG_DATA_HOME:-$HOME/.local/share}/voculinux-ibus/engine.pid")"
voculinux
```
Missing system packages: see [INSTALL.md](INSTALL.md) or [DISTRO_COMPATIBILITY.md](DISTRO_COMPATIBILITY.md).
@@ -196,7 +196,7 @@ See the [full changelog](https://github.com/VocaHQ/vocalinux/releases/tag/v0.18.
- Installer package map covers cairo headers on openSUSE, Void, Solus and Alpine (#937)
- evdev monitors remapper virtual keyboards ungrabbed so remappers like keyd keep working (#932)
- The install section on vocalinux.com showcases the .deb, .rpm, Snap, Flatpak and AUR packages (#929)
- The install section on voculinux.com showcases the .deb, .rpm, Snap, Flatpak and AUR packages (#929)
- The remote `curl | bash` install path is gated end to end in CI (#898)
AppImage, Flatpak, and Snap still ship whisper.cpp only.
@@ -273,7 +273,7 @@ See the [full changelog](https://github.com/VocaHQ/vocalinux/releases/tag/v0.18.
- Audio: stop passing an explicit index when zero devices enumerate; View Logs closes via the titlebar X (#891, #892)
- Snap gains `hardware-observe` so hotkeys can read input devices (#858, fixes #857 reported by @RhysU)
- Installer installs hash-pinned dependencies and build tools, and is split into sourced modules with a generated distro package map (#856, #862, #872 by @sesav)
- AUR `vocalinux-bin` ships the AppImage with per-arch digests; releases publish a signed self-hosted Flatpak OSTree remote; a snap-promote workflow gates stable promotion (#879, #875, #881, fixes #817, #785, #783)
- AUR `voculinux-bin` ships the AppImage with per-arch digests; releases publish a signed self-hosted Flatpak OSTree remote; a snap-promote workflow gates stable promotion (#879, #875, #881, fixes #817, #785, #783)
- VocaGateway can run locally from Settings → Advanced (podman-first) (#774)
- Dependency advisories cleared and workflow tokens scoped to repository reads (#869, #865, #866 by @Mr-Sunglasses, #870)
- Settings dialog consolidated: guard flags and widget construction in one place each (#878, fixes #793)
@@ -359,7 +359,7 @@ See the [full changelog](https://github.com/VocaHQ/vocalinux/releases/tag/v0.17.
- **CI**: gate AUR PKGBUILD builds on every PR (#772 by @sesav)
- **CI / docs**: test the distros the docs promise and fix docs drift (#773 by @sesav)
- **Site**: VocaGateway family card is Beta; README logo, badges, and privacy copy (#765 by @jatinkrmalik, #764)
- **Snap**: v0.16.2 `latest/edge` (rev 7) has no `uinput` plug. `sudo snap connect vocalinux:uinput` errors with `snap "vocalinux" has no plug named "uinput"`. Dictation only reaches XWayland apps. (v0.17.0+ added the plug, but the Store denied it, so later revisions drop it again and type via the RemoteDesktop portal.) (#823)
- **Snap**: v0.16.2 `latest/edge` (rev 7) has no `uinput` plug. `sudo snap connect voculinux:uinput` errors with `snap "voculinux" has no plug named "uinput"`. Dictation only reaches XWayland apps. (v0.17.0+ added the plug, but the Store denied it, so later revisions drop it again and type via the RemoteDesktop portal.) (#823)
See the [full changelog](https://github.com/VocaHQ/vocalinux/releases/tag/v0.16.2).
@@ -453,7 +453,7 @@ See the [full changelog](https://github.com/VocaHQ/vocalinux/releases/tag/v0.16.
- CUDA device 0 note for dual NVIDIA (#644)
- Discord and VocaHQ README shields; VocaHQ URL migration; VocaGateway rename (#695, #696, #697)
- Discord invite and X handle point at VocaHQ (#722)
- vocalinux.com restyled to the Voca family workbench; Open Graph card uses the flat Tux (#728, #729)
- voculinux.com restyled to the Voca family workbench; Open Graph card uses the flat Tux (#728, #729)
- Website copy drops the stale 100% offline claim and marks VocaWin as alpha on the site (#717)
- Codeberg mirror tag force-push (#633)
- Installer hardening, Justfile in place of Makefile, and uv lockfiles with pinned build inputs. Epic #701 remains open (#700, #705 by @sesav)
+49 -49
View File
@@ -1,10 +1,10 @@
# User guide
How to use Vocalinux day to day. Install first: [INSTALL.md](INSTALL.md).
How to use Voculinux day to day. Install first: [INSTALL.md](INSTALL.md).
## Getting started
1. Launch Vocalinux (`vocalinux` or the application menu)
1. Launch Voculinux (`voculinux` or the application menu)
2. Find the microphone icon in the system tray
3. Start dictation with the tray menu or your keyboard shortcut
4. Speak into the focused application; text is injected when an utterance completes
@@ -12,7 +12,7 @@ How to use Vocalinux day to day. Install first: [INSTALL.md](INSTALL.md).
### Start on login
Enable **Start on Login** from the first-run dialog, tray menu, or Settings. Vocalinux writes an XDG autostart entry (`~/.config/autostart/vocalinux.desktop`) and starts as a normal user app (`--start-minimized`). It does not create a systemd service.
Enable **Start on Login** from the first-run dialog, tray menu, or Settings. Voculinux writes an XDG autostart entry (`~/.config/autostart/voculinux.desktop`) and starts as a normal user app (`--start-minimized`). It does not create a systemd service.
Works on common desktop environments (GNOME, KDE, Xfce, Cinnamon, MATE, LXQt). Minimal window-manager sessions may need their own autostart helper.
@@ -26,15 +26,15 @@ Works on common desktop environments (GNOME, KDE, Xfce, Cinnamon, MATE, LXQt). M
### Dictation formatting
Vocalinux capitalizes the start of dictation and letters after `.`, `!`, or `?`. Each completed utterance leaves a trailing space so the next session does not glue onto the previous sentence.
Voculinux capitalizes the start of dictation and letters after `.`, `!`, or `?`. Each completed utterance leaves a trailing space so the next session does not glue onto the previous sentence.
### Dictating into terminals
When Vocalinux injects through the clipboard (the usual Wayland / ydotool path), it sends **Ctrl+V** in ordinary text fields and **Ctrl+Shift+V** in terminal emulator windows. Auto-detect works on X11 and on Hyprland, Sway, and niri. On GNOME or KDE Wayland, set **Settings → Dictation → Clipboard Paste Shortcut** to **Ctrl+Shift+V**.
When Voculinux injects through the clipboard (the usual Wayland / ydotool path), it sends **Ctrl+V** in ordinary text fields and **Ctrl+Shift+V** in terminal emulator windows. Auto-detect works on X11 and on Hyprland, Sway, and niri. On GNOME or KDE Wayland, set **Settings → Dictation → Clipboard Paste Shortcut** to **Ctrl+Shift+V**.
On non-US layouts such as German Neo, that chord uses the key that types **v** on the active layout (not physical KEY_V). Nested terminal panels inside an IDE are often invisible to window-class detection. If paste lands as a literal `^V` or does nothing, open **Settings → Dictation → Clipboard Paste Shortcut** and choose **Ctrl+Shift+V**.
On X11, **Paste long dictations** opts in to clipboard-pasting dictations of 30 or more characters instead of typing them key by key. It is off by default. Vocalinux restores the previous clipboard contents after pasting unless **Copy to Clipboard** is enabled. If the clipboard contains an image or other non-text content, Vocalinux types the dictation and leaves that content alone.
On X11, **Paste long dictations** opts in to clipboard-pasting dictations of 30 or more characters instead of typing them key by key. It is off by default. Voculinux restores the previous clipboard contents after pasting unless **Copy to Clipboard** is enabled. If the clipboard contains an image or other non-text content, Voculinux types the dictation and leaves that content alone.
The clipboard copy behind these pastes is temporary: your previous clipboard comes back right after. When the copy goes through `wl-copy` 2.2 or newer, it is also marked sensitive (`wl-copy --sensitive`), and clipboard managers that honor that hint, such as Klipper or cliphist, keep it out of their history. Older `wl-copy` builds and X11 or XWayland pastes (`xclip`/`xsel`) have no such hint, so there the dictated text can still show up in history. With **Settings → Dictation → Copy to Clipboard** on, the dictated text is an ordinary copy and stays in history.
@@ -46,11 +46,11 @@ Open **Settings → Audio → Input Device** to select a specific microphone or
**System Default**. A valid explicit microphone selection uses that device and
bypasses the System Default preference below.
With **System Default**, Vocalinux leaves valid default or virtual inputs under
With **System Default**, Voculinux leaves valid default or virtual inputs under
the audio system's control rather than pinning a hardware device.
On ALSA only, if PortAudio substitutes arbitrary hardware for the default input,
Vocalinux prefers an input-capable `pulse` PCM on the same host API to follow the
Voculinux prefers an input-capable `pulse` PCM on the same host API to follow the
microphone selected in desktop sound settings. If no suitable `pulse` PCM exists,
it keeps PortAudio's fallback device and logs a warning.
@@ -112,7 +112,7 @@ Parakeet runs NVIDIA NeMo ASR models through sherpa-onnx. The default bundle is
Pick the language you dictate in from **Language**, or leave it on auto-detect.
If you work in more than one language and switch keyboard layouts to do it, turn
on **Follow keyboard layout** instead. Vocalinux then reads your active layout at
on **Follow keyboard layout** instead. Voculinux then reads your active layout at
the start of every dictation and uses the matching language, so switching layout
switches dictation language with it. The Language picker greys out while this is
on and shows what your current layout resolves to; turning it off pins that
@@ -127,31 +127,31 @@ the configured primary layout.
### Activation via a KDE Plasma global shortcut
Instead of the built-in hotkey listener, you can let your desktop's global
shortcut system trigger Vocalinux. On Wayland the built-in listener reads
shortcut system trigger Voculinux. On Wayland the built-in listener reads
`/dev/input` (requiring membership in the `input` group and effectively acting
as a system-wide key reader). Delegating activation to the compositor avoids
this entirely: no `/dev/input` access and no `input` group needed just to
start/stop dictation. Text injection is unaffected.
Enable it in Vocalinux:
Enable it in Voculinux:
1. Open **Settings → Shortcuts** (the Keyboard Shortcuts group on the Dictation page)
2. Turn on **External Activation (Desktop Shortcut)**
The change applies immediately; you do not need to restart. The built-in key
listener stops, and a running instance exposes a D-Bus service on the session
bus (`com.vocalinux.Vocalinux`). The CLI can forward commands to it:
bus (`com.voculinux.Voculinux`). The CLI can forward commands to it:
```bash
vocalinux --toggle # start if idle, stop if active
vocalinux --start # start voice typing
vocalinux --stop # stop voice typing
voculinux --toggle # start if idle, stop if active
voculinux --start # start voice typing
voculinux --stop # stop voice typing
```
Then bind a compositor shortcut to `vocalinux --toggle` on a native install.
Then bind a compositor shortcut to `voculinux --toggle` on a native install.
For Flatpak, bind the `gdbus` command in
[Running without device access](../packaging/flatpak/README.md#running-without-device-access)
instead, because `vocalinux --toggle` is not on the host PATH. A desktop
instead, because `voculinux --toggle` is not on the host PATH. A desktop
shortcut only sends the key press, so it can toggle dictation but cannot
support push-to-talk because it never sees the release. On KDE Plasma:
@@ -159,16 +159,16 @@ support push-to-talk because it never sees the release. On KDE Plasma:
(older Plasma: **System Settings -> Shortcuts -> Custom Shortcuts -> Edit ->
New -> Global Shortcut -> Command/URL**).
2. Bind a key combination of your choice to the command `vocalinux --toggle`
2. Bind a key combination of your choice to the command `voculinux --toggle`
for a native install. For Flatpak, use the D-Bus command linked above.
Now your chosen key combination toggles dictation, handled by the compositor
rather than by Vocalinux reading the keyboard directly. This works the same way
rather than by Voculinux reading the keyboard directly. This works the same way
on other compositors that support binding a key to a command (e.g. GNOME custom
shortcuts, Sway/Hyprland `bindsym`/`bind`).
As an advanced alternative, you can set the same option in
`~/.config/vocalinux/config.json` under `shortcuts`:
`~/.config/voculinux/config.json` under `shortcuts`:
```json
"shortcuts": {
@@ -176,8 +176,8 @@ As an advanced alternative, you can set the same option in
}
```
Quit Vocalinux before editing that file so the running app cannot overwrite
the edit from its cached config. Start Vocalinux again after saving.
Quit Voculinux before editing that file so the running app cannot overwrite
the edit from its cached config. Start Voculinux again after saving.
### Model size (whisper.cpp / Whisper)
@@ -193,13 +193,13 @@ For whisper.cpp, also pick a **Specialization**: standard multilingual, English-
### Removing unused models
If leftover files are on disk that are not the model currently selected, **Unused downloads** appears under the model info card. Expand it to delete leftovers one at a time. Confirming removes those files from `~/.local/share/vocalinux`. Packaged system-wide VOSK models are left alone.
If leftover files are on disk that are not the model currently selected, **Unused downloads** appears under the model info card. Expand it to delete leftovers one at a time. Confirming removes those files from `~/.local/share/voculinux`. Packaged system-wide VOSK models are left alone.
### GPU
whisper.cpp prefers Vulkan when the bundled pywhispercpp libraries include it, then CUDA, then CPU. Host tools such as `vulkaninfo` only describe the machine. The engine follows the libraries actually loaded. On multi-GPU machines a discrete Vulkan device is preferred; override under **Settings → Performance → Vulkan GPU**. Check logs with `vocalinux --debug`.
whisper.cpp prefers Vulkan when the bundled pywhispercpp libraries include it, then CUDA, then CPU. Host tools such as `vulkaninfo` only describe the machine. The engine follows the libraries actually loaded. On multi-GPU machines a discrete Vulkan device is preferred; override under **Settings → Performance → Vulkan GPU**. Check logs with `voculinux --debug`.
Pip wheels of pywhispercpp are often CUDA builds. In that case Vocalinux uses CUDA device 0. `install.sh` rebuilds pywhispercpp with Vulkan or CUDA when it can.
Pip wheels of pywhispercpp are often CUDA builds. In that case Voculinux uses CUDA device 0. `install.sh` rebuilds pywhispercpp with Vulkan or CUDA when it can.
### Auto-pause and keep-alive
@@ -226,16 +226,16 @@ recording. This option is off by default.
## CLI
```bash
vocalinux --help
vocalinux --version
vocalinux --debug
vocalinux --engine whisper_cpp
vocalinux --engine faster_whisper
vocalinux --engine parakeet
vocalinux --model medium.en-q5_0
vocalinux --wayland
vocalinux --start-minimized
vocalinux --transcribe-file meeting.wav # diarized transcript on stdout, then exits
voculinux --help
voculinux --version
voculinux --debug
voculinux --engine whisper_cpp
voculinux --engine faster_whisper
voculinux --engine parakeet
voculinux --model medium.en-q5_0
voculinux --wayland
voculinux --start-minimized
voculinux --transcribe-file meeting.wav # diarized transcript on stdout, then exits
```
## Custom Dictionary Support
@@ -243,15 +243,15 @@ vocalinux --transcribe-file meeting.wav # diarized transcript on stdout, then
Open **Settings → Custom Dictionary** to configure two separate capabilities:
- **Custom terms** bias recognition toward product names, people, and jargon.
They are read from `~/.config/vocalinux/dictionary.txt` by default, as UTF-8
They are read from `~/.config/voculinux/dictionary.txt` by default, as UTF-8
with one term per line. Blank lines and `#` comments are allowed, so the same
file remains friendly to an accessibility scanner. Use the add/remove editor
or choose a different readable terms file with the file picker.
- **Transcript corrections** replace a known misheard word or phrase after
transcription, for example `super base` with `Supabase`. Corrections are
stored separately in `~/.config/vocalinux/custom-dictionary-corrections.json`.
stored separately in `~/.config/voculinux/custom-dictionary-corrections.json`.
VocaLinux re-reads both files before each completed dictation segment, so an
Voculinux re-reads both files before each completed dictation segment, so an
external edit applies to the next segment without restarting the app. Vocabulary
bias works with Whisper, whisper.cpp, and Faster Whisper. Corrections work with
every engine, including VOSK, Parakeet, and the configured remote API.
@@ -261,10 +261,10 @@ command-like misrecognition from acting, but avoid replacements that create a
voice command unless that is intentional. Correction replacements are not
automatically added to recognition bias.
For a one-session terms override, start Vocalinux with:
For a one-session terms override, start Voculinux with:
```bash
vocalinux --dictionary-file /path/to/dictionary.txt
voculinux --dictionary-file /path/to/dictionary.txt
```
This temporarily enables terms from that file without changing saved settings;
@@ -275,7 +275,7 @@ transcript corrections.
### Post-Processing
Vocalinux can pipe each transcription result through a user-defined script before injecting it into your application. This lets you apply custom transformations — for example, grammar correction, abbreviation expansion, or domain-specific formatting.
Voculinux can pipe each transcription result through a user-defined script before injecting it into your application. This lets you apply custom transformations — for example, grammar correction, abbreviation expansion, or domain-specific formatting.
**To configure:**
1. Open Settings from the tray icon menu (right-click)
@@ -295,19 +295,19 @@ Vocalinux can pipe each transcription result through a user-defined script befor
#!/bin/bash
tr '[:lower:]' '[:upper:]'
```
Make the script executable (`chmod +x`) before setting the path in Vocalinux.
Make the script executable (`chmod +x`) before setting the path in Voculinux.
## Troubleshooting
```bash
vocalinux --debug
voculinux --debug
```
See [TROUBLESHOOTING.md](TROUBLESHOOTING.md) for tray, audio, injection, and model issues. Distro notes: [DISTRO_COMPATIBILITY.md](DISTRO_COMPATIBILITY.md). Updates: [UPDATE.md](UPDATE.md). Help channels: [SUPPORT.md](../SUPPORT.md).
### Text injection backend
Vocalinux types your dictated text using one of several backends. It picks one
Voculinux types your dictated text using one of several backends. It picks one
automatically, and on most desktops the automatic choice is correct.
Autodetection can be wrong, though, and it fails in a way that is easy to
@@ -316,7 +316,7 @@ applications, IBus reports the text as delivered while nothing appears. If
dictation works in some windows (typically XWayland ones, like a browser) but
silently does nothing in others, that is the symptom.
Pin the backend explicitly in `~/.config/vocalinux/config.json`:
Pin the backend explicitly in `~/.config/voculinux/config.json`:
```json
{
@@ -350,19 +350,19 @@ particular application. Pinning `ibus` keeps the IBus path; pinning anything
else turns it off.
To try a backend for a single run without changing the saved setting, set
`VOCALINUX_FORCE_BACKEND`, which overrides the config value. Set it to `auto`
`VOCULINUX_FORCE_BACKEND`, which overrides the config value. Set it to `auto`
to ignore a saved pin for that run:
```bash
VOCALINUX_FORCE_BACKEND=wtype vocalinux --debug
VOCULINUX_FORCE_BACKEND=wtype voculinux --debug
```
The setting and environment override are read at startup, so restart Vocalinux
The setting and environment override are read at startup, so restart Voculinux
after editing `config.json`. The startup log first records a backend pin request;
it does not prove the backend was available or that text reached the focused
application. Later logs identify a fallback when a pin was not applied.
If a pinned tool is unavailable, Vocalinux warns and continues with its normal
If a pinned tool is unavailable, Voculinux warns and continues with its normal
fallback selection. `portal` needs a desktop implementing the
`org.freedesktop.portal.RemoteDesktop` interface (GNOME and KDE Plasma do;
most wlroots compositors do not). `ydotool` also needs a usable `/dev/uinput`