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
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Report a bug to help improve Vocalinux
|
||||
about: Report a bug to help improve Voculinux
|
||||
title: "[BUG] "
|
||||
labels: bug
|
||||
assignees: ''
|
||||
@@ -32,7 +32,7 @@ If applicable, attach screenshots.
|
||||
|
||||
- **OS / distro**: (e.g. Ubuntu 24.04)
|
||||
- **Python version**: (e.g. 3.12; 3.11+ required)
|
||||
- **Vocalinux version**: (`vocalinux --version`)
|
||||
- **Voculinux version**: (`voculinux --version`)
|
||||
- **Install method**: (installer / AppImage / AUR / Flatpak / Snap / source / PyPI)
|
||||
- **Display server**: (X11 / Wayland)
|
||||
- **Desktop environment**: (e.g. GNOME, KDE Plasma)
|
||||
@@ -41,7 +41,7 @@ If applicable, attach screenshots.
|
||||
|
||||
## Debug logs
|
||||
|
||||
Run `vocalinux --debug` and paste the relevant output:
|
||||
Run `voculinux --debug` and paste the relevant output:
|
||||
|
||||
```
|
||||
[paste logs here]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: Feature Request
|
||||
about: Suggest an idea for Vocalinux
|
||||
about: Suggest an idea for Voculinux
|
||||
title: "[FEATURE] "
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
@@ -8,7 +8,7 @@ assignees: ''
|
||||
|
||||
## Feature description
|
||||
|
||||
What you would like Vocalinux to do.
|
||||
What you would like Voculinux to do.
|
||||
|
||||
## Problem
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ app:
|
||||
- "src/**/*"
|
||||
- "pyproject.toml"
|
||||
- "MANIFEST.in"
|
||||
- "vocalinux.desktop"
|
||||
- "voculinux.desktop"
|
||||
|
||||
# Next.js website
|
||||
web:
|
||||
|
||||
@@ -41,7 +41,7 @@ jobs:
|
||||
|
||||
export GIT_SSH_COMMAND="ssh -i ~/.ssh/codeberg_mirror -o IdentitiesOnly=yes"
|
||||
|
||||
git remote add codeberg git@codeberg.org:jatinkrmalik/vocalinux.git
|
||||
git remote add codeberg git@codeberg.org:jatinkrmalik/voculinux.git
|
||||
git push codeberg --all
|
||||
# Force tags so the mirror stays aligned with GitHub when a tag
|
||||
# already exists on Codeberg (retagged release or prior partial sync).
|
||||
|
||||
@@ -11,7 +11,7 @@ on:
|
||||
- 'uv.lock'
|
||||
- 'requirements/**'
|
||||
- 'src/vocalinux/version.py'
|
||||
- 'vocalinux.desktop'
|
||||
- 'voculinux.desktop'
|
||||
- '.github/workflows/distro-test-matrix.yml'
|
||||
pull_request:
|
||||
branches: [ main, master ]
|
||||
@@ -23,7 +23,7 @@ on:
|
||||
- 'uv.lock'
|
||||
- 'requirements/**'
|
||||
- 'src/vocalinux/version.py'
|
||||
- 'vocalinux.desktop'
|
||||
- 'voculinux.desktop'
|
||||
- '.github/workflows/distro-test-matrix.yml'
|
||||
workflow_dispatch:
|
||||
|
||||
|
||||
@@ -71,8 +71,8 @@ jobs:
|
||||
- name: Build and bundle
|
||||
uses: flatpak/flatpak-github-actions/flatpak-builder@79327416609af08178ad73b352877e51450790b3 # v6
|
||||
with:
|
||||
bundle: vocalinux-${{ matrix.arch }}.flatpak
|
||||
manifest-path: packaging/flatpak/com.vocalinux.Vocalinux.yml
|
||||
bundle: voculinux-${{ matrix.arch }}.flatpak
|
||||
manifest-path: packaging/flatpak/com.voculinux.Voculinux.yml
|
||||
# The action appends -${arch} and restore-keys is
|
||||
# `flatpak-builder-${arch}`, so the key has to start with that
|
||||
# prefix. Putting the packaging hash first made every lock
|
||||
@@ -80,7 +80,7 @@ jobs:
|
||||
# github.sha in the key forced a full rebuild every run.
|
||||
cache-key: flatpak-builder-${{ matrix.arch }}-${{ hashFiles('packaging/flatpak/**') }}
|
||||
arch: ${{ matrix.arch }}
|
||||
artifact-name: vocalinux-flatpak-${{ matrix.arch }}
|
||||
artifact-name: voculinux-flatpak-${{ matrix.arch }}
|
||||
# Flathub mirrors screenshots at submission time; mirror locally so the
|
||||
# builddir linter does not flag the external screenshot URL.
|
||||
mirror-screenshots-url: https://dl.flathub.org/media
|
||||
|
||||
@@ -77,12 +77,12 @@ jobs:
|
||||
- name: Cache AppImage build tools
|
||||
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||
with:
|
||||
path: ~/.cache/vocalinux-appimage
|
||||
path: ~/.cache/voculinux-appimage
|
||||
key: appimage-native-${{ runner.arch }}-${{ steps.native-cache.outputs.id }}
|
||||
|
||||
- name: Build AppImage (x86_64)
|
||||
env:
|
||||
VOCALINUX_APPIMAGE_REQUIRE_VULKAN: "1"
|
||||
VOCULINUX_APPIMAGE_REQUIRE_VULKAN: "1"
|
||||
run: |
|
||||
bash packaging/appimage/docker-build.sh dist/*.whl "${{ steps.version.outputs.version }}" dist
|
||||
ls -la dist/*.AppImage
|
||||
@@ -159,13 +159,13 @@ jobs:
|
||||
#### Quick Install (Recommended)
|
||||
Download the wheel file below and install:
|
||||
\`\`\`bash
|
||||
pip install vocalinux-${{ steps.version.outputs.version }}-py3-none-any.whl
|
||||
pip install voculinux-${{ steps.version.outputs.version }}-py3-none-any.whl
|
||||
\`\`\`
|
||||
|
||||
#### From PyPI (Stable)
|
||||
For the latest stable release:
|
||||
\`\`\`bash
|
||||
pip install vocalinux
|
||||
pip install voculinux
|
||||
\`\`\`
|
||||
|
||||
#### Using Install Script
|
||||
@@ -176,8 +176,8 @@ jobs:
|
||||
#### AppImage (no install, no root)
|
||||
Download the \`.AppImage\` matching your CPU (\`x86_64\` or \`aarch64\`) below:
|
||||
\`\`\`bash
|
||||
chmod +x Vocalinux-${{ steps.version.outputs.version }}-x86_64.AppImage
|
||||
./Vocalinux-${{ steps.version.outputs.version }}-x86_64.AppImage
|
||||
chmod +x Voculinux-${{ steps.version.outputs.version }}-x86_64.AppImage
|
||||
./Voculinux-${{ steps.version.outputs.version }}-x86_64.AppImage
|
||||
\`\`\`
|
||||
Requires \`xdotool\`/\`wtype\`/\`ydotool\` on the host for text injection, same as the PyPI install path.
|
||||
|
||||
@@ -197,16 +197,16 @@ jobs:
|
||||
|
||||
### Files
|
||||
|
||||
- **\`vocalinux-${{ steps.version.outputs.version }}-py3-none-any.whl\`** - Python wheel (recommended)
|
||||
- **\`vocalinux-${{ steps.version.outputs.version }}.tar.gz\`** - Source distribution
|
||||
- **\`Vocalinux-${{ steps.version.outputs.version }}-x86_64.AppImage\`** - Self-contained, no install (Intel/AMD)
|
||||
- **\`Vocalinux-${{ steps.version.outputs.version }}-aarch64.AppImage\`** - Self-contained, no install (ARM64, added shortly after this release is published)
|
||||
- **\`voculinux-${{ steps.version.outputs.version }}-py3-none-any.whl\`** - Python wheel (recommended)
|
||||
- **\`voculinux-${{ steps.version.outputs.version }}.tar.gz\`** - Source distribution
|
||||
- **\`Voculinux-${{ steps.version.outputs.version }}-x86_64.AppImage\`** - Self-contained, no install (Intel/AMD)
|
||||
- **\`Voculinux-${{ steps.version.outputs.version }}-aarch64.AppImage\`** - Self-contained, no install (ARM64, added shortly after this release is published)
|
||||
|
||||
---
|
||||
|
||||
### Links
|
||||
|
||||
- [Documentation](https://vocalinux.com)
|
||||
- [Documentation](https://voculinux.com)
|
||||
- [Report Issues](https://github.com/VocaHQ/vocalinux/issues)
|
||||
- [Other Releases](https://github.com/VocaHQ/vocalinux/releases)
|
||||
|
||||
@@ -242,7 +242,7 @@ jobs:
|
||||
- name: Upload artifacts (backup)
|
||||
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||
with:
|
||||
name: vocalinux-nightly-${{ steps.version.outputs.version }}
|
||||
name: voculinux-nightly-${{ steps.version.outputs.version }}
|
||||
path: dist/
|
||||
retention-days: 7
|
||||
|
||||
@@ -296,12 +296,12 @@ jobs:
|
||||
- name: Cache AppImage build tools
|
||||
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||
with:
|
||||
path: ~/.cache/vocalinux-appimage
|
||||
path: ~/.cache/voculinux-appimage
|
||||
key: appimage-native-${{ runner.arch }}-${{ steps.native-cache.outputs.id }}
|
||||
|
||||
- name: Build AppImage (aarch64)
|
||||
env:
|
||||
VOCALINUX_APPIMAGE_REQUIRE_VULKAN: "1"
|
||||
VOCULINUX_APPIMAGE_REQUIRE_VULKAN: "1"
|
||||
run: |
|
||||
bash packaging/appimage/docker-build.sh dist/*.whl "${{ needs.nightly.outputs.version }}" dist
|
||||
ls -la dist/*.AppImage
|
||||
|
||||
@@ -15,11 +15,11 @@ env:
|
||||
# Build against the supported floor (requires-python in pyproject.toml).
|
||||
PYTHON_VERSION: '3.11'
|
||||
# The dedicated "tap" repo and the URL Pages serves it at. A custom
|
||||
# domain (e.g. flatpak.vocalinux.com) overrides both via the vars.
|
||||
# domain (e.g. flatpak.voculinux.com) overrides both via the vars.
|
||||
FLATPAK_REMOTE_REPO: ${{ vars.FLATPAK_REMOTE_REPO || 'VocaHQ/vocalinux-flatpak' }}
|
||||
FLATPAK_REMOTE_URL: ${{ vars.FLATPAK_REMOTE_URL || 'https://vocahq.github.io/vocalinux-flatpak/repo' }}
|
||||
FLATPAKREPO_URL: ${{ vars.FLATPAKREPO_URL || 'https://vocahq.github.io/vocalinux-flatpak/vocahq.flatpakrepo' }}
|
||||
FLATPAKREF_URL: ${{ vars.FLATPAKREF_URL || 'https://vocahq.github.io/vocalinux-flatpak/com.vocalinux.Vocalinux.flatpakref' }}
|
||||
FLATPAK_REMOTE_URL: ${{ vars.FLATPAK_REMOTE_URL || 'https://vocahq.github.io/voculinux-flatpak/repo' }}
|
||||
FLATPAKREPO_URL: ${{ vars.FLATPAKREPO_URL || 'https://vocahq.github.io/voculinux-flatpak/vocahq.flatpakrepo' }}
|
||||
FLATPAKREF_URL: ${{ vars.FLATPAKREF_URL || 'https://vocahq.github.io/voculinux-flatpak/com.voculinux.Voculinux.flatpakref' }}
|
||||
|
||||
jobs:
|
||||
build-and-release:
|
||||
@@ -101,12 +101,12 @@ jobs:
|
||||
- name: Cache AppImage build tools
|
||||
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||
with:
|
||||
path: ~/.cache/vocalinux-appimage
|
||||
path: ~/.cache/voculinux-appimage
|
||||
key: appimage-native-${{ runner.arch }}-${{ steps.native-cache.outputs.id }}
|
||||
|
||||
- name: Build AppImage (x86_64)
|
||||
env:
|
||||
VOCALINUX_APPIMAGE_REQUIRE_VULKAN: "1"
|
||||
VOCULINUX_APPIMAGE_REQUIRE_VULKAN: "1"
|
||||
run: |
|
||||
bash packaging/appimage/docker-build.sh dist/*.whl "${{ steps.get_version.outputs.VERSION }}" dist
|
||||
ls -la dist/*.AppImage
|
||||
@@ -151,7 +151,7 @@ jobs:
|
||||
```bash
|
||||
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak remote-add --if-not-exists vocahq __FLATPAKREPO_URL__
|
||||
flatpak install vocahq com.vocalinux.Vocalinux
|
||||
flatpak install vocahq com.voculinux.Voculinux
|
||||
```
|
||||
|
||||
Or download the `.flatpak` matching your CPU (`x86_64` or `aarch64`, attached
|
||||
@@ -161,8 +161,8 @@ jobs:
|
||||
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak install flathub org.gnome.Platform//50
|
||||
|
||||
flatpak install --user ./Vocalinux-__VERSION__-x86_64.flatpak
|
||||
flatpak run com.vocalinux.Vocalinux
|
||||
flatpak install --user ./Voculinux-__VERSION__-x86_64.flatpak
|
||||
flatpak run com.voculinux.Voculinux
|
||||
```
|
||||
EOF
|
||||
else
|
||||
@@ -175,8 +175,8 @@ jobs:
|
||||
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak install flathub org.gnome.Platform//50
|
||||
|
||||
flatpak install --user ./Vocalinux-__VERSION__-x86_64.flatpak
|
||||
flatpak run com.vocalinux.Vocalinux
|
||||
flatpak install --user ./Voculinux-__VERSION__-x86_64.flatpak
|
||||
flatpak run com.voculinux.Voculinux
|
||||
```
|
||||
EOF
|
||||
if [ "$prerelease" = true ]; then
|
||||
@@ -223,7 +223,7 @@ jobs:
|
||||
### From Source
|
||||
```bash
|
||||
git clone https://github.com/VocaHQ/vocalinux.git
|
||||
cd vocalinux
|
||||
cd voculinux
|
||||
./install.sh
|
||||
```
|
||||
|
||||
@@ -231,10 +231,10 @@ jobs:
|
||||
```bash
|
||||
# Install the Linux system packages first:
|
||||
# GTK/AppIndicator, PortAudio, and xdotool/wtype are required.
|
||||
python3 -m venv ~/.local/share/vocalinux-pypi/venv --system-site-packages
|
||||
source ~/.local/share/vocalinux-pypi/venv/bin/activate
|
||||
pip install vocalinux
|
||||
vocalinux
|
||||
python3 -m venv ~/.local/share/voculinux-pypi/venv --system-site-packages
|
||||
source ~/.local/share/voculinux-pypi/venv/bin/activate
|
||||
pip install voculinux
|
||||
voculinux
|
||||
```
|
||||
|
||||
PyPI installs the Python package only. For automatic system dependency,
|
||||
@@ -243,15 +243,15 @@ jobs:
|
||||
|
||||
### Arch Linux (AUR)
|
||||
```bash
|
||||
yay -S vocalinux
|
||||
yay -S voculinux
|
||||
```
|
||||
|
||||
### AppImage (no install, no root)
|
||||
Download the `.AppImage` matching your CPU (`x86_64` or `aarch64`, the latter attached
|
||||
shortly after this release is published) below:
|
||||
```bash
|
||||
chmod +x Vocalinux-${{ steps.get_version.outputs.VERSION }}-x86_64.AppImage
|
||||
./Vocalinux-${{ steps.get_version.outputs.VERSION }}-x86_64.AppImage
|
||||
chmod +x Voculinux-${{ steps.get_version.outputs.VERSION }}-x86_64.AppImage
|
||||
./Voculinux-${{ steps.get_version.outputs.VERSION }}-x86_64.AppImage
|
||||
```
|
||||
Still requires `xdotool`/`wtype`/`ydotool` on the host for text injection, same as the PyPI path.
|
||||
|
||||
@@ -260,10 +260,10 @@ jobs:
|
||||
attached shortly after this release is published):
|
||||
```bash
|
||||
# Debian / Ubuntu
|
||||
sudo apt install ./vocalinux_*_amd64.deb
|
||||
sudo apt install ./voculinux_*_amd64.deb
|
||||
|
||||
# Fedora
|
||||
sudo dnf install ./vocalinux-*.x86_64.rpm
|
||||
sudo dnf install ./voculinux-*.x86_64.rpm
|
||||
```
|
||||
Thin packages: Python, GTK, PyGObject and the AppIndicator typelib come from the
|
||||
distro, and `apt`/`dnf` resolves them. Only `pywhispercpp` and `pynput` are
|
||||
@@ -278,13 +278,13 @@ jobs:
|
||||
${{ steps.flatpak_notes.outputs.flatpak }}
|
||||
|
||||
### Snap
|
||||
Tagged releases also attach `vocalinux_${{ steps.get_version.outputs.VERSION }}_amd64.snap`
|
||||
Tagged releases also attach `voculinux_${{ steps.get_version.outputs.VERSION }}_amd64.snap`
|
||||
and try the Snap Store (`edge` and `candidate`). `stable` is promoted
|
||||
from candidate after QA by the `snap-promote.yml` dispatch workflow.
|
||||
Wayland typing runs through the RemoteDesktop portal; the snap ships no `uinput` plug.
|
||||
The GitHub `.snap` is also the sideload while a Store revision lags:
|
||||
```bash
|
||||
sudo snap install --dangerous ./vocalinux_${{ steps.get_version.outputs.VERSION }}_amd64.snap
|
||||
sudo snap install --dangerous ./voculinux_${{ steps.get_version.outputs.VERSION }}_amd64.snap
|
||||
```
|
||||
`--dangerous` is required because this file is not a Store revision. It will not
|
||||
refresh from the Store. amd64 only.
|
||||
@@ -298,7 +298,7 @@ jobs:
|
||||
```
|
||||
Each artifact also carries GitHub build provenance, which ties it to this workflow run:
|
||||
```bash
|
||||
gh attestation verify Vocalinux-${{ steps.get_version.outputs.VERSION }}-x86_64.AppImage \
|
||||
gh attestation verify Voculinux-${{ steps.get_version.outputs.VERSION }}-x86_64.AppImage \
|
||||
--repo ${{ github.repository }}
|
||||
```
|
||||
|
||||
@@ -343,12 +343,12 @@ jobs:
|
||||
- name: Cache AppImage build tools
|
||||
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||
with:
|
||||
path: ~/.cache/vocalinux-appimage
|
||||
path: ~/.cache/voculinux-appimage
|
||||
key: appimage-native-${{ runner.arch }}-${{ steps.native-cache.outputs.id }}
|
||||
|
||||
- name: Build AppImage (aarch64)
|
||||
env:
|
||||
VOCALINUX_APPIMAGE_REQUIRE_VULKAN: "1"
|
||||
VOCULINUX_APPIMAGE_REQUIRE_VULKAN: "1"
|
||||
run: |
|
||||
bash packaging/appimage/docker-build.sh dist/*.whl "${{ steps.get_version.outputs.VERSION }}" dist
|
||||
ls -la dist/*.AppImage
|
||||
@@ -492,8 +492,8 @@ jobs:
|
||||
- name: Build and bundle
|
||||
uses: flatpak/flatpak-github-actions/flatpak-builder@79327416609af08178ad73b352877e51450790b3 # v6
|
||||
with:
|
||||
bundle: Vocalinux-${{ steps.get_version.outputs.VERSION }}-x86_64.flatpak
|
||||
manifest-path: packaging/flatpak/com.vocalinux.Vocalinux.yml
|
||||
bundle: Voculinux-${{ steps.get_version.outputs.VERSION }}-x86_64.flatpak
|
||||
manifest-path: packaging/flatpak/com.voculinux.Voculinux.yml
|
||||
# Same prefix rule as flatpak.yml: restore-keys is
|
||||
# `flatpak-builder-${arch}`. The action appends -${arch} again.
|
||||
cache-key: flatpak-builder-x86_64-${{ hashFiles('packaging/flatpak/**') }}
|
||||
@@ -506,7 +506,7 @@ jobs:
|
||||
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||
with:
|
||||
name: flatpak-x86_64
|
||||
path: Vocalinux-${{ steps.get_version.outputs.VERSION }}-x86_64.flatpak
|
||||
path: Voculinux-${{ steps.get_version.outputs.VERSION }}-x86_64.flatpak
|
||||
if-no-files-found: error
|
||||
retention-days: 7
|
||||
|
||||
@@ -529,8 +529,8 @@ jobs:
|
||||
- name: Build and bundle
|
||||
uses: flatpak/flatpak-github-actions/flatpak-builder@79327416609af08178ad73b352877e51450790b3 # v6
|
||||
with:
|
||||
bundle: Vocalinux-${{ steps.get_version.outputs.VERSION }}-aarch64.flatpak
|
||||
manifest-path: packaging/flatpak/com.vocalinux.Vocalinux.yml
|
||||
bundle: Voculinux-${{ steps.get_version.outputs.VERSION }}-aarch64.flatpak
|
||||
manifest-path: packaging/flatpak/com.voculinux.Voculinux.yml
|
||||
cache-key: flatpak-builder-aarch64-${{ hashFiles('packaging/flatpak/**') }}
|
||||
arch: aarch64
|
||||
upload-artifact: false
|
||||
@@ -540,7 +540,7 @@ jobs:
|
||||
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||
with:
|
||||
name: flatpak-aarch64
|
||||
path: Vocalinux-${{ steps.get_version.outputs.VERSION }}-aarch64.flatpak
|
||||
path: Voculinux-${{ steps.get_version.outputs.VERSION }}-aarch64.flatpak
|
||||
if-no-files-found: error
|
||||
retention-days: 7
|
||||
|
||||
@@ -715,27 +715,27 @@ jobs:
|
||||
echo '[Flatpak Repo]'
|
||||
echo 'Title=VocaHQ'
|
||||
echo "Url=${FLATPAK_REMOTE_URL}"
|
||||
echo 'Homepage=https://vocalinux.com'
|
||||
echo 'Comment=Official Vocalinux Flatpak remote'
|
||||
echo 'Description=Self-hosted Vocalinux Flatpak repository'
|
||||
echo 'Icon=https://vocalinux.com/icon-512x512.png'
|
||||
echo 'Homepage=https://voculinux.com'
|
||||
echo 'Comment=Official Voculinux Flatpak remote'
|
||||
echo 'Description=Self-hosted Voculinux Flatpak repository'
|
||||
echo 'Icon=https://voculinux.com/icon-512x512.png'
|
||||
echo 'DefaultBranch=stable'
|
||||
echo "GPGKey=$(base64 -w0 "$RUNNER_TEMP/pubkey.gpg")"
|
||||
} > publish/vocahq.flatpakrepo
|
||||
{
|
||||
echo '[Flatpak Ref]'
|
||||
echo 'Version=1'
|
||||
echo 'Title=Vocalinux'
|
||||
echo 'Name=com.vocalinux.Vocalinux'
|
||||
echo 'Title=Voculinux'
|
||||
echo 'Name=com.voculinux.Voculinux'
|
||||
echo 'Branch=stable'
|
||||
echo "Url=${FLATPAK_REMOTE_URL}"
|
||||
echo 'SuggestRemoteName=vocahq'
|
||||
echo 'RuntimeRepo=https://dl.flathub.org/repo/flathub.flatpakrepo'
|
||||
echo 'IsRuntime=false'
|
||||
echo 'Homepage=https://vocalinux.com'
|
||||
echo 'Icon=https://vocalinux.com/icon-512x512.png'
|
||||
echo 'Homepage=https://voculinux.com'
|
||||
echo 'Icon=https://voculinux.com/icon-512x512.png'
|
||||
echo "GPGKey=$(base64 -w0 "$RUNNER_TEMP/pubkey.gpg")"
|
||||
} > publish/com.vocalinux.Vocalinux.flatpakref
|
||||
} > publish/com.voculinux.Voculinux.flatpakref
|
||||
cp "$RUNNER_TEMP/pubkey.gpg" publish/vocahq.gpg
|
||||
grep -v GPGKey publish/vocahq.flatpakrepo
|
||||
sed -e "s|__FLATPAKREPO_URL__|${FLATPAKREPO_URL}|g" \
|
||||
@@ -751,7 +751,7 @@ jobs:
|
||||
external_repository: ${{ env.FLATPAK_REMOTE_REPO }}
|
||||
publish_dir: ./publish
|
||||
publish_branch: gh-pages
|
||||
commit_message: 'Vocalinux ${{ github.ref_name }}'
|
||||
commit_message: 'Voculinux ${{ github.ref_name }}'
|
||||
|
||||
attach-flatpak:
|
||||
name: Attach Flatpak bundles
|
||||
@@ -854,7 +854,7 @@ jobs:
|
||||
id-token: write # PyPI trusted publishing; there is no API token to leak
|
||||
environment:
|
||||
name: pypi
|
||||
url: https://pypi.org/project/vocalinux/
|
||||
url: https://pypi.org/project/voculinux/
|
||||
steps:
|
||||
# Not a rebuild: the artifact attached to the GitHub release, so one
|
||||
# checksum describes both.
|
||||
@@ -892,14 +892,14 @@ jobs:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
gh release download "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" \
|
||||
--pattern 'vocalinux-*.tar.gz' --pattern SHA256SUMS --dir release-source
|
||||
--pattern 'voculinux-*.tar.gz' --pattern SHA256SUMS --dir release-source
|
||||
- name: Verify provenance and prepare the exact source PKGBUILD
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
uv run --python "$(command -v python)" --locked --only-group release-build \
|
||||
python scripts/prepare_aur_source.py \
|
||||
--sdist release-source/vocalinux-*.tar.gz --manifest release-source/SHA256SUMS \
|
||||
--sdist release-source/voculinux-*.tar.gz --manifest release-source/SHA256SUMS \
|
||||
--tag "$GITHUB_REF_NAME" --source-commit "$GITHUB_SHA" --output build/aur-source
|
||||
- name: Build and install the exact source PKGBUILD on Arch
|
||||
run: |
|
||||
@@ -944,7 +944,7 @@ jobs:
|
||||
if: steps.aur.outputs.configured == 'true'
|
||||
uses: KSXGitHub/github-actions-deploy-aur@084b0d9b15415bf9cdb65d44dad1efe37a354050 # v4.2.0
|
||||
with:
|
||||
pkgname: vocalinux
|
||||
pkgname: voculinux
|
||||
pkgbuild: aur-source/PKGBUILD
|
||||
updpkgsums: 'false'
|
||||
commit_username: ${{ secrets.AUR_USERNAME }}
|
||||
@@ -985,7 +985,7 @@ jobs:
|
||||
run: |
|
||||
set -euo pipefail
|
||||
TAG="${GITHUB_REF#refs/tags/v}"
|
||||
PKGBUILD=packaging/aur/vocalinux-bin/PKGBUILD
|
||||
PKGBUILD=packaging/aur/voculinux-bin/PKGBUILD
|
||||
sed -i "s/^pkgver=.*/pkgver=${TAG//-/}/; s/^_tag=.*/_tag=${TAG}/; s/^pkgrel=.*/pkgrel=1/" "$PKGBUILD"
|
||||
grep -E '^(pkgver|_tag|pkgrel)=' "$PKGBUILD"
|
||||
|
||||
@@ -998,21 +998,21 @@ jobs:
|
||||
set -euo pipefail
|
||||
tag="${GITHUB_REF_NAME#v}"
|
||||
for arch in x86_64 aarch64; do
|
||||
url="https://github.com/VocaHQ/vocalinux/releases/download/${GITHUB_REF_NAME}/Vocalinux-${tag}-${arch}.AppImage"
|
||||
url="https://github.com/VocaHQ/vocalinux/releases/download/${GITHUB_REF_NAME}/Voculinux-${tag}-${arch}.AppImage"
|
||||
sum="$(curl -fsSL "$url" | sha256sum | cut -d' ' -f1)"
|
||||
sed -i "s/^sha256sums_${arch}=('[0-9a-f]*')/sha256sums_${arch}=('${sum}')/" \
|
||||
packaging/aur/vocalinux-bin/PKGBUILD
|
||||
packaging/aur/voculinux-bin/PKGBUILD
|
||||
done
|
||||
|
||||
- name: Publish AUR -bin package
|
||||
if: steps.aur.outputs.configured == 'true'
|
||||
uses: KSXGitHub/github-actions-deploy-aur@084b0d9b15415bf9cdb65d44dad1efe37a354050 # v4.2.0
|
||||
with:
|
||||
pkgname: vocalinux-bin
|
||||
# The -bin PKGBUILD names local sources (vocalinux.desktop,
|
||||
# vocalinux.svg, LICENSE); publishing the whole directory mirrors
|
||||
pkgname: voculinux-bin
|
||||
# The -bin PKGBUILD names local sources (voculinux.desktop,
|
||||
# voculinux.svg, LICENSE); publishing the whole directory mirrors
|
||||
# them into the AUR repo instead of shipping a lone PKGBUILD.
|
||||
asset_dir: packaging/aur/vocalinux-bin
|
||||
asset_dir: packaging/aur/voculinux-bin
|
||||
# Sums are pinned in the step above for BOTH arches; regenerating
|
||||
# here would only refresh the x86_64 array.
|
||||
updpkgsums: 'false'
|
||||
@@ -1195,5 +1195,5 @@ jobs:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: ./web/out
|
||||
publish_branch: gh-pages
|
||||
cname: vocalinux.com
|
||||
cname: voculinux.com
|
||||
force_orphan: true
|
||||
|
||||
@@ -77,7 +77,7 @@ jobs:
|
||||
run: |
|
||||
set -euo pipefail
|
||||
VERSION="${TAG#v}"
|
||||
/snap/bin/snapcraft status vocalinux | tee /tmp/snap-status.txt
|
||||
/snap/bin/snapcraft status voculinux | tee /tmp/snap-status.txt
|
||||
# POSIX: mawk has no \S — use a literal non-space class.
|
||||
row=$(awk '/^[^ \t]/ { track = $1 }
|
||||
track == "latest" && $1 == "candidate" { print $2, $3; exit }
|
||||
@@ -110,7 +110,7 @@ jobs:
|
||||
row=$(awk '/^[^ \t]/ { track = $1 }
|
||||
track == "latest" && $1 == "candidate" { print $2, $3; exit }
|
||||
track == "latest" && $3 == "candidate" { print $4, $5; exit }' \
|
||||
<(/snap/bin/snapcraft status vocalinux))
|
||||
<(/snap/bin/snapcraft status voculinux))
|
||||
read -r seen_version revision <<<"$row"
|
||||
if [ "${revision:-}" != "$REVISION" ] || [ "$seen_version" != "$VERSION" ]; then
|
||||
echo "latest/candidate moved on (now version=${seen_version:-none} revision=${revision:-none}); aborting instead of promoting the stale revision" >&2
|
||||
@@ -123,5 +123,5 @@ jobs:
|
||||
REVISION: ${{ steps.candidate.outputs.revision }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
/snap/bin/snapcraft release vocalinux "$REVISION" latest/stable
|
||||
/snap/bin/snapcraft status vocalinux
|
||||
/snap/bin/snapcraft release voculinux "$REVISION" latest/stable
|
||||
/snap/bin/snapcraft status voculinux
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Vocalinux CI
|
||||
name: Voculinux CI
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -51,7 +51,7 @@ jobs:
|
||||
# entry and the icon into the AppDir.
|
||||
- 'install.sh'
|
||||
- 'install.d/**'
|
||||
- 'vocalinux.desktop'
|
||||
- 'voculinux.desktop'
|
||||
- 'resources/**'
|
||||
- 'justfile'
|
||||
# scripts/ is guarded by tests/ and one of them is executed by the
|
||||
@@ -65,7 +65,7 @@ jobs:
|
||||
- '.pre-commit-config.yaml'
|
||||
- '.github/workflows/unified-pipeline.yml'
|
||||
- '.github/workflows/release.yml'
|
||||
# The AUR gate builds packaging/aur/vocalinux/PKGBUILD from this
|
||||
# The AUR gate builds packaging/aur/voculinux/PKGBUILD from this
|
||||
# tree. Its depends= mirror pyproject.toml, so every python change
|
||||
# reaches the gate through the python filter above; this filter
|
||||
# exists so a PKGBUILD-only change runs the gate without dragging
|
||||
@@ -350,12 +350,12 @@ jobs:
|
||||
- name: Cache AppImage build tools
|
||||
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||
with:
|
||||
path: ~/.cache/vocalinux-appimage
|
||||
path: ~/.cache/voculinux-appimage
|
||||
key: appimage-native-${{ runner.arch }}-${{ steps.native-cache.outputs.id }}
|
||||
|
||||
- name: Build AppImage
|
||||
env:
|
||||
VOCALINUX_APPIMAGE_REQUIRE_VULKAN: "1"
|
||||
VOCULINUX_APPIMAGE_REQUIRE_VULKAN: "1"
|
||||
run: |
|
||||
VERSION=$(grep -oP '__version__\s*=\s*"\K[^"]+' src/vocalinux/version.py)
|
||||
WHEEL=$(ls dist/*.whl)
|
||||
@@ -365,7 +365,7 @@ jobs:
|
||||
- name: Upload AppImage artifact
|
||||
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||
with:
|
||||
name: vocalinux-appimage-${{ matrix.arch }}
|
||||
name: voculinux-appimage-${{ matrix.arch }}
|
||||
path: dist/*.AppImage
|
||||
retention-days: 7
|
||||
|
||||
@@ -394,7 +394,7 @@ jobs:
|
||||
- name: Download the AppImage built above
|
||||
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
||||
with:
|
||||
name: vocalinux-appimage-x86_64
|
||||
name: voculinux-appimage-x86_64
|
||||
path: dist
|
||||
|
||||
- name: Boot it on ${{ matrix.distro }}
|
||||
@@ -434,7 +434,7 @@ jobs:
|
||||
run: |
|
||||
uv run --python "$(command -v python)" --locked --only-group release-build \
|
||||
python scripts/prepare_aur_source.py \
|
||||
--local-unattested --sdist dist/vocalinux-*.tar.gz --output build/aur-source
|
||||
--local-unattested --sdist dist/voculinux-*.tar.gz --output build/aur-source
|
||||
|
||||
- name: Build the PKGBUILD on Arch
|
||||
run: |
|
||||
@@ -445,7 +445,7 @@ jobs:
|
||||
|
||||
# The .deb and .rpm exist to be installed and run, so the gate does exactly
|
||||
# that: build both in the pinned Debian 12 image release.yml uses, then
|
||||
# install them in distro containers and run vocalinux --version plus an
|
||||
# install them in distro containers and run voculinux --version plus an
|
||||
# import smoke. debian:12 and ubuntu:24.04 exercise the .deb's dependency
|
||||
# list (and the vendored cp311/cp312 wheels), fedora:42 the .rpm's.
|
||||
native-build:
|
||||
@@ -535,7 +535,7 @@ jobs:
|
||||
- name: Upload the verified snap
|
||||
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||
with:
|
||||
name: vocalinux-snap-amd64
|
||||
name: voculinux-snap-amd64
|
||||
path: ${{ steps.build.outputs.snap }}
|
||||
if-no-files-found: error
|
||||
retention-days: 7
|
||||
@@ -628,5 +628,5 @@ jobs:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: ./web/out
|
||||
publish_branch: gh-pages
|
||||
cname: vocalinux.com
|
||||
cname: voculinux.com
|
||||
force_orphan: true
|
||||
|
||||
@@ -24,7 +24,7 @@ env/
|
||||
ENV/
|
||||
.env
|
||||
.venv/
|
||||
activate-vocalinux.sh
|
||||
activate-voculinux.sh
|
||||
|
||||
# Local development settings
|
||||
.vscode/
|
||||
|
||||
@@ -23,7 +23,7 @@ ENV UV_PYTHON_INSTALL_DIR=/opt/uv-python \
|
||||
UV_LINK_MODE=copy
|
||||
RUN uv sync --locked --extra dev --extra vad
|
||||
|
||||
# Make the project venv the default interpreter, so `python`, `pytest` and `vocalinux` work offline.
|
||||
# Make the project venv the default interpreter, so `python`, `pytest` and `voculinux` work offline.
|
||||
ENV VIRTUAL_ENV=/src/.venv \
|
||||
PATH=/src/.venv/bin:$PATH \
|
||||
PYTHONPATH=/src \
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Threat model
|
||||
|
||||
Vocalinux is a desktop voice-dictation app for Linux (X11 and Wayland). It records the
|
||||
Voculinux is a desktop voice-dictation app for Linux (X11 and Wayland). It records the
|
||||
microphone, runs speech recognition, and types the result into whichever window has focus.
|
||||
It runs as the logged-in user, never as root, and has no server of its own. Python
|
||||
sources are under `src/vocalinux/`; the tests are under `tests/`.
|
||||
@@ -26,9 +26,9 @@ has the user's privileges. Input from these places is untrusted:
|
||||
(`docs/HTTP_REMOTE.md`), audio goes to a user-configured OpenAI-compatible or
|
||||
whisper.cpp HTTP endpoint, and the JSON response is parsed and *typed into the
|
||||
focused window*. Treat the server as hostile. It may return oversized, malformed,
|
||||
or control-character-laden responses, try to make Vocalinux type key sequences,
|
||||
or control-character-laden responses, try to make Voculinux type key sequences,
|
||||
shell commands or terminal escapes, or redirect requests elsewhere.
|
||||
4. **Local VocaGateway embed** (`gateway_embed/`). Vocalinux can start a
|
||||
4. **Local VocaGateway embed** (`gateway_embed/`). Voculinux can start a
|
||||
[VocaGateway](https://github.com/VocaHQ/vocagateway) container via podman or docker
|
||||
compose. It writes the compose `.env` (`runner.py`, with `_IMAGE_RE` guarding image
|
||||
refs) and fetches pairing JSON and QR SVG from the gateway over HTTP (`pairing.py`,
|
||||
@@ -66,7 +66,7 @@ has the user's privileges. Input from these places is untrusted:
|
||||
- Out of scope: `web/` (the marketing website), `docs/`, `packaging/` (AppImage,
|
||||
Flatpak, AUR, Snap recipes), `snap/`, `.github/` workflows, and bugs that live
|
||||
in third-party engines (whisper.cpp, VOSK, sherpa-onnx, onnxruntime, torch)
|
||||
themselves. Report those upstream, unless Vocalinux calls them unsafely.
|
||||
themselves. Report those upstream, unless Voculinux calls them unsafely.
|
||||
|
||||
## How to exercise it
|
||||
- `python -m pytest -q tests/` runs the full suite offline. Hardware and display tests
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Pre-commit hooks for Vocalinux
|
||||
# Pre-commit hooks for Voculinux
|
||||
# Run: pre-commit run --all-files
|
||||
|
||||
repos:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# AGENTS.md — Vocalinux
|
||||
# AGENTS.md — Voculinux
|
||||
|
||||
Voice dictation for Linux: GTK 3 tray app (Python) plus a Next.js marketing site in `web/`. Default speech engine is **whisper.cpp** (`pywhispercpp`); OpenAI Whisper, Vosk, and a user-configured remote API are optional. Do not invent features, user counts, or privacy claims.
|
||||
|
||||
@@ -13,18 +13,18 @@ Never create a branch, commit, or open a pull request in the primary checkout. A
|
||||
|
||||
```bash
|
||||
git fetch origin
|
||||
git worktree add /tmp/vocalinux-<task> -b <type>/<short-name> origin/main
|
||||
git worktree add /tmp/voculinux-<task> -b <type>/<short-name> origin/main
|
||||
|
||||
# All edits, commits, and `gh pr create` happen inside that worktree.
|
||||
|
||||
git worktree remove /tmp/vocalinux-<task>
|
||||
git worktree remove /tmp/voculinux-<task>
|
||||
git worktree prune
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- One worktree per branch, one branch per PR
|
||||
- Place worktrees **outside** the primary working tree (`/tmp/vocalinux-<task>` or a sibling directory such as `../.worktrees/vocalinux-<task>`)
|
||||
- Place worktrees **outside** the primary working tree (`/tmp/voculinux-<task>` or a sibling directory such as `../.worktrees/voculinux-<task>`)
|
||||
- Never run two tasks in the same worktree
|
||||
- Never commit directly to `main`
|
||||
- Clean up the worktree after the PR is pushed
|
||||
@@ -97,7 +97,7 @@ just remote-install-gate debian:12 # remote curl|bash path end to end against H
|
||||
just verify-release # check a published release as published (needs gh)
|
||||
just reproducible-wheel # independent locked wheel builds; stages verified dist/ (needs uv)
|
||||
just pre-commit # pre-commit run --all-files
|
||||
just run-debug # vocalinux --debug
|
||||
just run-debug # voculinux --debug
|
||||
just run-source-debug
|
||||
```
|
||||
|
||||
@@ -127,7 +127,7 @@ Use **uv 0.13.3** for `just lock` and `just export-check`, matching CI. Other ve
|
||||
| pywhispercpp | Pinned in `install.sh` as `PYWHISPERCPP_VERSION` (keep in sync with `uv.lock`) |
|
||||
| Installer build tools | `[dependency-groups].installer-build` exports to `requirements/installer-build.txt`. Bootstrap uses hashed wheels on new and reused venvs; source builds use these tools without build isolation. Its setuptools `>=83` floor keeps the pinned installer tools patched; do not add it to `[build-system]` (Arch). Backend rebuilds select pywhispercpp's complete hash block from `runtime.txt` via `scripts/installer_requirements.py`, with `--no-deps` so they cannot replace the runtime |
|
||||
| Release build tools | `[dependency-groups].release-build` exports to `requirements/release-build.txt`. `scripts/build_reproducible_wheel.py` builds in two fresh source trees/venvs with hashed tools and `--no-isolation`, compares wheel bytes, and stages only canonical distributions in `dist/`. These build-only venvs exclude system site-packages: host setuptools plugins must not influence locked builds, and packaging does not import GTK. Repeat runs clean recognized diagnostics and staged archives matching retained canonical digests; staged copies are deleted first so interrupted cleanup remains retryable. Unrelated/modified files are preserved and block cleanup. Never wipe all of `build/`. PR and release CI use Python 3.11 and pinned uv. Failed build outputs/logs stay under `build/reproducible-wheel/`, excluded from release artifacts |
|
||||
| AUR source publication | Use the canonical release sdist, not a GitHub tag archive. `scripts/prepare_aur_source.py` (run with the locked `release-build` group) requires its published checksum and provenance from the exact release workflow/tag/commit before preparing a pinned PKGBUILD. Release CI builds/installs that unchanged recipe on current Arch; publication consumes only the gated artifact with `updpkgsums: false`. PR/local fixtures must explicitly use `--local-unattested` and are never publication inputs. `just aur-gate` keeps distributions, diagnostics and tooling in its own temporary directory, leaving shared packaging outputs and dev environments untouched; failures retain that directory and print its path. `vocalinux-bin` publication depends only on release creation and both AppImages, not the source gate or global checksums. Existing AUR provider stubs/pinned import smoke remain limited as documented in `docs/AUR.md` |
|
||||
| AUR source publication | Use the canonical release sdist, not a GitHub tag archive. `scripts/prepare_aur_source.py` (run with the locked `release-build` group) requires its published checksum and provenance from the exact release workflow/tag/commit before preparing a pinned PKGBUILD. Release CI builds/installs that unchanged recipe on current Arch; publication consumes only the gated artifact with `updpkgsums: false`. PR/local fixtures must explicitly use `--local-unattested` and are never publication inputs. `just aur-gate` keeps distributions, diagnostics and tooling in its own temporary directory, leaving shared packaging outputs and dev environments untouched; failures retain that directory and print its path. `voculinux-bin` publication depends only on release creation and both AppImages, not the source gate or global checksums. Existing AUR provider stubs/pinned import smoke remain limited as documented in `docs/AUR.md` |
|
||||
| Installer Whisper export | Compiled universally from Python 3.11, constrained by `runtime.txt` and `installer-build.txt` to keep shared pins consistent. Uses a `+cpu` torch pin and best-match index resolution so the CPU index's older copies of shared packages do not downgrade the runtime |
|
||||
| Remote installer | After cloning, hand off to the tagged `install.sh` with the original arguments and remote venv path. The installer and its exports must come from the same revision, including when the tag predates the pinned installer |
|
||||
| `[vad]` extra | `onnxruntime` for Silero VAD |
|
||||
@@ -136,7 +136,7 @@ Use **uv 0.13.3** for `just lock` and `just export-check`, matching CI. Other ve
|
||||
| AppImage PyGObject | Pinned separately in `requirements/appimage.in`, and below 3.52: the AppImage bundles its own interpreter and builds PyGObject against the base image's girepository-1.0, while uv.lock's 3.56 needs girepository-2.0 (glib 2.80+) |
|
||||
| AppImage build inputs | Base image, tooling, interpreter, shaderc and the Vulkan headers are pinned in `packaging/appimage/tool_checksums.txt`. Build with `just appimage` (docker) — building on the host ships the host's glibc, which is what kept the AppImage off Debian 12 |
|
||||
| AppImage boot matrix | `packaging/appimage/boot-test.sh` runs the finished AppImage in distro containers, and the matrix in `unified-pipeline.yml` must keep distros both older and newer than the build image: the old ones prove the glibc floor, the new ones catch a bundle that breaks the host binaries it spawns. A distro added there needs its package recipe in the script — `tests/test_appimage_packaging.py` checks both |
|
||||
| Native packages (.deb / .rpm) | Thin packages built by nfpm in the pinned Debian 12 image (`packaging/native/tool_checksums.txt` pins the image and the nfpm releases). Python, GTK and PyGObject come from the distro; only `pywhispercpp` and `pynput` are vendored under `/usr/lib/vocalinux/vendor` (unpackaged on Debian/Fedora). `packaging/native/smoke-test.sh` installs the package per-distro and runs `vocalinux --version` plus an import smoke — `tests/test_native_packaging.py` keeps the deps lists, vendored set and CI matrix consistent offline |
|
||||
| Native packages (.deb / .rpm) | Thin packages built by nfpm in the pinned Debian 12 image (`packaging/native/tool_checksums.txt` pins the image and the nfpm releases). Python, GTK and PyGObject come from the distro; only `pywhispercpp` and `pynput` are vendored under `/usr/lib/voculinux/vendor` (unpackaged on Debian/Fedora). `packaging/native/smoke-test.sh` installs the package per-distro and runs `voculinux --version` plus an import smoke — `tests/test_native_packaging.py` keeps the deps lists, vendored set and CI matrix consistent offline |
|
||||
| Snap Python inputs | `snap/local/build.py` uses `requirements/installer-build.txt` in an isolated, build-only venv and installs `requirements/runtime.txt` with hashes, no dependency resolution or build isolation. The project installs without dependencies or index access; never strip PyGObject from `pyproject.toml`. GI comes from the GNOME extension. Keep portable CPU flags and force the pinned pywhispercpp sdist without a wheel cache. PR/release CI installs the real artifact via `snap/local/smoke-test.sh` before publication. Native Ubuntu/GNOME/Snapcraft inputs remain channel-controlled, not byte-for-byte reproducible — see `docs/SNAP.md` |
|
||||
| Flatpak deps | `packaging/flatpak/python3-dependencies.yaml` is generated from `requirements/vad.txt` (runtime dependencies plus the `[vad]` extra) by `scripts/sync_flatpak_deps.py` (`just flatpak-deps`, which `just lock` runs itself). It resolves each artifact by the digest uv already recorded, so the Flatpak downloads the bytes in `uv.lock`; `onnxruntime` is pinned to CPython wheels for each Flatpak architecture and the GNOME 50 Python version. The project installs there with `pip3 install --no-deps`, so nothing inside the build evaluates `pyproject.toml` — `tests/test_flatpak_packaging.py` checks the invariant offline |
|
||||
| Speech models | Verified against digests pinned in `src/vocalinux/utils/model_checksums.txt` before install, by both `install.sh` and the runtime downloaders. **Fails closed** — an unpinned model is refused. Regenerate with `just model-checksums` (never by hand); `tests/test_model_checksums.py` fails if it falls behind. whisper.cpp URLs use a pinned Hugging Face commit, never `main` |
|
||||
@@ -152,7 +152,7 @@ src/vocalinux/
|
||||
│ ├── capture.py # PortAudio capture sources and device handling
|
||||
│ ├── pipewire.py # PipeWire system-audio capture
|
||||
│ └── playback_ducker.py # lower default sink while dictating
|
||||
├── single_instance.py # $XDG_DATA_HOME/vocalinux/instance.lock
|
||||
├── single_instance.py # $XDG_DATA_HOME/voculinux/instance.lock
|
||||
├── auto_pause_monitor.py # unload model while configured apps run
|
||||
├── model_keepalive.py # idle unload
|
||||
├── suspend_handler.py # logind PrepareForSleep
|
||||
@@ -243,9 +243,9 @@ Site-only work: `web/AGENTS.md` (commands, layout map). Product claims: `web/PRO
|
||||
## Runtime (any Linux dev machine)
|
||||
|
||||
- Create runtime/dev venvs with `--system-site-packages`. Build-only venvs for `scripts/build_reproducible_wheel.py`, `just aur-gate` preparation and `snap/local/build.py` are the exception: exclude host packages to keep the locked tools isolated; the Snap runtime gets GI from its GNOME command chain. Never prune the developer environment to run a packaging gate
|
||||
- Kill the app by PID, never `pkill -f vocalinux` (matches editors, shells, and cwd paths)
|
||||
- Stale instance: `$XDG_DATA_HOME/vocalinux/instance.lock` (default `~/.local/share/vocalinux/instance.lock`)
|
||||
- Default dictation shortcut: hold Right Alt (push-to-talk). Existing `~/.config/vocalinux/config.json` wins
|
||||
- Kill the app by PID, never `pkill -f voculinux` (matches editors, shells, and cwd paths)
|
||||
- Stale instance: `$XDG_DATA_HOME/voculinux/instance.lock` (default `~/.local/share/voculinux/instance.lock`)
|
||||
- Default dictation shortcut: hold Right Alt (push-to-talk). Existing `~/.config/voculinux/config.json` wins
|
||||
- Headless speech smoke: `pywhispercpp.model.Model` + `CommandProcessor` (first run may download the tiny model)
|
||||
|
||||
Update this file when commands, layout, or agent rules change.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Contributing to Vocalinux
|
||||
# Contributing to Voculinux
|
||||
|
||||
Thanks for your interest in contributing. This guide covers setup, style, testing, and pull requests.
|
||||
|
||||
@@ -18,8 +18,8 @@ Participation is covered by our [Code of Conduct](CODE_OF_CONDUCT.md). Be respec
|
||||
### Automated (recommended)
|
||||
|
||||
```bash
|
||||
git clone https://github.com/YOUR-USERNAME/vocalinux.git
|
||||
cd vocalinux
|
||||
git clone https://github.com/YOUR-USERNAME/voculinux.git
|
||||
cd voculinux
|
||||
./install.sh --dev
|
||||
```
|
||||
|
||||
@@ -152,7 +152,7 @@ just typecheck # mypy src/
|
||||
### Project structure
|
||||
|
||||
```
|
||||
vocalinux/
|
||||
voculinux/
|
||||
├── src/vocalinux/ # Application
|
||||
│ ├── main.py
|
||||
│ ├── speech_recognition/ # Engines + command processor
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
include vocalinux.desktop
|
||||
include voculinux.desktop
|
||||
include resources/icons/scalable/*.svg
|
||||
include resources/sounds/*.wav
|
||||
recursive-include src/vocalinux/resources *
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<div align="center">
|
||||
|
||||
<img src="https://vocalinux.com/brand/vocalinux-mark-circle.svg" width="50" height="50" alt="Vocalinux">
|
||||
<img src="https://voculinux.com/brand/voculinux-mark-circle.svg" width="50" height="50" alt="Voculinux">
|
||||
|
||||
# Vocalinux
|
||||
# Voculinux
|
||||
|
||||
**Voice dictation for Linux**
|
||||
|
||||
@@ -22,20 +22,20 @@
|
||||
[](https://github.com/VocaHQ/vocalinux/releases/latest)
|
||||
[](https://github.com/VocaHQ/vocalinux/releases/latest)
|
||||
[](#flatpak-any-distro)
|
||||
[](https://snapcraft.io/vocalinux)
|
||||
[](https://aur.archlinux.org/packages/vocalinux)
|
||||
[](https://pypi.org/project/vocalinux/)
|
||||
[](https://snapcraft.io/voculinux)
|
||||
[](https://aur.archlinux.org/packages/voculinux)
|
||||
[](https://pypi.org/project/voculinux/)
|
||||
[](packaging/nix/README.md)
|
||||
|
||||
[](https://discord.gg/t6muquAJbm)
|
||||
[](https://vocahq.com)
|
||||
[](https://x.com/vocahq)
|
||||
|
||||
[Website](https://vocalinux.com) · [Install](#install) · [Docs](#documentation) · [Releases](https://github.com/VocaHQ/vocalinux/releases)
|
||||
[Website](https://voculinux.com) · [Install](#install) · [Docs](#documentation) · [Releases](https://github.com/VocaHQ/vocalinux/releases)
|
||||
|
||||
</div>
|
||||
|
||||
Vocalinux turns speech into typed text in whatever app has focus. It is a free, AGPL-3.0-licensed desktop app for X11 and Wayland. After you download a model, local engines (whisper.cpp by default, plus OpenAI Whisper, Faster Whisper, VOSK, and Parakeet) run speech-to-text on your machine. An optional remote HTTP API is off unless you configure it.
|
||||
Voculinux turns speech into typed text in whatever app has focus. It is a free, AGPL-3.0-licensed desktop app for X11 and Wayland. After you download a model, local engines (whisper.cpp by default, plus OpenAI Whisper, Faster Whisper, VOSK, and Parakeet) run speech-to-text on your machine. An optional remote HTTP API is off unless you configure it.
|
||||
|
||||
No Voca account is required. Models download once. After that, speech-to-text stays on your machine.
|
||||
|
||||
@@ -54,7 +54,7 @@ No Voca account is required. Models download once. After that, speech-to-text st
|
||||
|
||||
## Screenshots
|
||||
|
||||
Vocalinux in action. Full gallery on the [website screenshots page](https://vocalinux.com/screenshots/).
|
||||
Voculinux in action. Full gallery on the [website screenshots page](https://voculinux.com/screenshots/).
|
||||
|
||||
### Product
|
||||
|
||||
@@ -161,7 +161,7 @@ For a specific release tag, see [GitHub Releases](https://github.com/VocaHQ/voca
|
||||
### Arch Linux (AUR)
|
||||
|
||||
```bash
|
||||
yay -S vocalinux
|
||||
yay -S voculinux
|
||||
```
|
||||
|
||||
See [docs/AUR.md](docs/AUR.md).
|
||||
@@ -172,28 +172,28 @@ Download the `x86_64` or `aarch64` AppImage from [Releases](https://github.com/V
|
||||
|
||||
### Distro packages (.deb / .rpm)
|
||||
|
||||
Download the `.deb` (Debian 12+, Ubuntu 24.04+) or `.rpm` (Fedora) matching your CPU from [Releases](https://github.com/VocaHQ/vocalinux/releases) and install with `sudo apt install ./vocalinux_*.deb` or `sudo dnf install ./vocalinux-*.rpm`. Thin packages: Python and GTK come from the distro. No auto-update; CPU whisper.cpp. Details in [docs/INSTALL.md](docs/INSTALL.md).
|
||||
Download the `.deb` (Debian 12+, Ubuntu 24.04+) or `.rpm` (Fedora) matching your CPU from [Releases](https://github.com/VocaHQ/vocalinux/releases) and install with `sudo apt install ./voculinux_*.deb` or `sudo dnf install ./voculinux-*.rpm`. Thin packages: Python and GTK come from the distro. No auto-update; CPU whisper.cpp. Details in [docs/INSTALL.md](docs/INSTALL.md).
|
||||
|
||||
### Flatpak (any distro)
|
||||
|
||||
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:
|
||||
@@ -201,21 +201,21 @@ Local build:
|
||||
```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
|
||||
```
|
||||
|
||||
Ships whisper.cpp with 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).
|
||||
|
||||
### Snap (Ubuntu Snap Store)
|
||||
|
||||
Listing: [snapcraft.io/vocalinux](https://snapcraft.io/vocalinux). `stable` is promoted from `candidate` after QA. Tagged releases also attach `vocalinux_<version>_amd64.snap` on GitHub.
|
||||
Listing: [snapcraft.io/voculinux](https://snapcraft.io/voculinux). `stable` is promoted from `candidate` after QA. Tagged releases also attach `voculinux_<version>_amd64.snap` on GitHub.
|
||||
|
||||
```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, 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.
|
||||
@@ -223,8 +223,8 @@ Native Wayland typing uses the RemoteDesktop portal: the compositor asks once on
|
||||
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: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:uinput # only in the v0.18.x sideload; the recipe no longer ships it
|
||||
```
|
||||
|
||||
### Nix / NixOS (flake)
|
||||
@@ -234,13 +234,13 @@ nix run github:VocaHQ/vocalinux # try it
|
||||
nix profile install github:VocaHQ/vocalinux
|
||||
```
|
||||
|
||||
The flake also ships `nixosModules.vocalinux` and `homeManagerModules.vocalinux` for declarative installs (`programs.vocalinux.enable = true`). The bundled pywhispercpp builds with Vulkan GPU inference. Details: [packaging/nix/README.md](packaging/nix/README.md).
|
||||
The flake also ships `nixosModules.voculinux` and `homeManagerModules.voculinux` for declarative installs (`programs.voculinux.enable = true`). The bundled pywhispercpp builds with Vulkan GPU inference. Details: [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
|
||||
# or pick the engine up front
|
||||
./install.sh --engine=whisper_cpp
|
||||
@@ -251,12 +251,12 @@ cd vocalinux
|
||||
### After installation
|
||||
|
||||
```bash
|
||||
vocalinux # if ~/.local/bin is on PATH
|
||||
voculinux # if ~/.local/bin is on PATH
|
||||
# or
|
||||
~/.local/share/vocalinux/venv/bin/vocalinux
|
||||
~/.local/share/voculinux/venv/bin/voculinux
|
||||
```
|
||||
|
||||
You can also launch Vocalinux from your application menu.
|
||||
You can also launch Voculinux from your application menu.
|
||||
|
||||
### Nightly builds
|
||||
|
||||
@@ -271,7 +271,7 @@ Daily builds from `main` appear on [Releases](https://github.com/VocaHQ/vocalinu
|
||||
| **Display** | X11 or Wayland |
|
||||
| **Hardware** | Microphone; GPU optional (Vulkan) |
|
||||
|
||||
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. Distribution notes: [docs/DISTRO_COMPATIBILITY.md](docs/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. Distribution notes: [docs/DISTRO_COMPATIBILITY.md](docs/DISTRO_COMPATIBILITY.md).
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -302,20 +302,20 @@ punctuation / line-break phrases in that language are also recognized
|
||||
### CLI
|
||||
|
||||
```bash
|
||||
vocalinux --help
|
||||
vocalinux --version
|
||||
vocalinux --debug
|
||||
vocalinux --engine whisper_cpp # default
|
||||
vocalinux --engine whisper
|
||||
vocalinux --engine faster_whisper
|
||||
vocalinux --engine vosk
|
||||
vocalinux --engine parakeet
|
||||
vocalinux --engine remote_api
|
||||
vocalinux --model medium
|
||||
vocalinux --model medium.en-q5_0 # exact whisper.cpp variant
|
||||
vocalinux --model large-v3-turbo
|
||||
vocalinux --wayland
|
||||
vocalinux --start-minimized
|
||||
voculinux --help
|
||||
voculinux --version
|
||||
voculinux --debug
|
||||
voculinux --engine whisper_cpp # default
|
||||
voculinux --engine whisper
|
||||
voculinux --engine faster_whisper
|
||||
voculinux --engine vosk
|
||||
voculinux --engine parakeet
|
||||
voculinux --engine remote_api
|
||||
voculinux --model medium
|
||||
voculinux --model medium.en-q5_0 # exact whisper.cpp variant
|
||||
voculinux --model large-v3-turbo
|
||||
voculinux --wayland
|
||||
voculinux --start-minimized
|
||||
```
|
||||
|
||||
### Autostart
|
||||
@@ -324,9 +324,9 @@ vocalinux --start-minimized
|
||||
|
||||
### Configuration
|
||||
|
||||
Stored at `~/.config/vocalinux/config.json`. Prefer the Settings dialog for day-to-day changes. **Settings → Speech Model** starts with a simple setup; expand **Advanced** for engine, size, and specialization. Set `post_processing.script_path` to an executable to transform each transcription result (stdin → stdout) before it is injected; leave empty to disable.
|
||||
Stored at `~/.config/voculinux/config.json`. Prefer the Settings dialog for day-to-day changes. **Settings → Speech Model** starts with a simple setup; expand **Advanced** for engine, size, and specialization. Set `post_processing.script_path` to an executable to transform each transcription result (stdin → stdout) before it is injected; leave empty to disable.
|
||||
|
||||
Neural VAD (Silero) is used when `onnxruntime` is available; install via `pip install "vocalinux[vad]"` for manual/PyPI installs. The installer attempts this automatically.
|
||||
Neural VAD (Silero) is used when `onnxruntime` is available; install via `pip install "voculinux[vad]"` for manual/PyPI installs. The installer attempts this automatically.
|
||||
|
||||
## Documentation
|
||||
|
||||
@@ -358,7 +358,7 @@ Report vulnerabilities privately per [SECURITY.md](SECURITY.md).
|
||||
|
||||
```bash
|
||||
git clone https://github.com/VocaHQ/vocalinux.git
|
||||
cd vocalinux
|
||||
cd voculinux
|
||||
./install.sh --dev
|
||||
source venv/bin/activate
|
||||
pytest
|
||||
@@ -379,11 +379,11 @@ Planned:
|
||||
|
||||
## Voca ecosystem
|
||||
|
||||
Vocalinux is part of [VocaHQ](https://vocahq.com). On-device speech-to-text first, one app per platform. Optional [VocaGateway](https://vocagateway.vocahq.com) is self-hosted and not on-device.
|
||||
Voculinux is part of [VocaHQ](https://vocahq.com). On-device speech-to-text first, one app per platform. Optional [VocaGateway](https://vocagateway.vocahq.com) is self-hosted and not on-device.
|
||||
|
||||
| Platform | Project | Website | GitHub |
|
||||
|----------|---------|---------|--------|
|
||||
| Linux | **VocaLinux** | [vocalinux.com](https://vocalinux.com) | [VocaHQ/vocalinux](https://github.com/VocaHQ/vocalinux) |
|
||||
| Linux | **Voculinux** | [voculinux.com](https://voculinux.com) | [VocaHQ/vocalinux](https://github.com/VocaHQ/vocalinux) |
|
||||
| macOS | **VocaMac** | [vocamac.com](https://vocamac.com) | [VocaHQ/vocamac](https://github.com/VocaHQ/vocamac) |
|
||||
| Windows | **VocaWin** | [vocawin.com](https://vocawin.com) | [VocaHQ/vocawin](https://github.com/VocaHQ/vocawin) |
|
||||
| Phone | **VocaPhone** | [vocaphone.vocahq.com](https://vocaphone.vocahq.com) | [VocaHQ/vocaphone](https://github.com/VocaHQ/vocaphone) |
|
||||
@@ -404,7 +404,7 @@ Bug reports, docs, and code are welcome. Start with [CONTRIBUTING.md](CONTRIBUTI
|
||||
Thanks to everyone who has contributed code, docs, or fixes:
|
||||
|
||||
<a href="https://github.com/VocaHQ/vocalinux/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=VocaHQ/vocalinux" alt="Vocalinux contributors" />
|
||||
<img src="https://contrib.rocks/image?repo=VocaHQ/vocalinux" alt="Voculinux contributors" />
|
||||
</a>
|
||||
|
||||
## Repository mirrors
|
||||
@@ -414,7 +414,7 @@ GitHub is the primary forge for issues, PRs, CI, and releases.
|
||||
| Role | URL |
|
||||
|------|-----|
|
||||
| Primary | https://github.com/VocaHQ/vocalinux |
|
||||
| Read-only mirror (Codeberg) | https://codeberg.org/jatinkrmalik/vocalinux |
|
||||
| Read-only mirror (Codeberg) | https://codeberg.org/jatinkrmalik/voculinux |
|
||||
|
||||
Open issues and pull requests on GitHub only.
|
||||
|
||||
@@ -440,7 +440,7 @@ offers `orukeet-v0.1.0`. It uses the existing local sherpa-onnx recognizer for
|
||||
engine stay unchanged.
|
||||
|
||||
The download comes from a pinned revision of
|
||||
[oruk/orukeet on Hugging Face](https://huggingface.co/oruk/orukeet). Vocalinux
|
||||
[oruk/orukeet on Hugging Face](https://huggingface.co/oruk/orukeet). Voculinux
|
||||
checks every file against its bundled SHA-256 pins and checks the publisher's
|
||||
release manifest against those same pins. The manifest download participates
|
||||
in Hugging Face's normal model-download accounting. Cached recognition works
|
||||
|
||||
@@ -20,7 +20,7 @@ Do not open a public GitHub issue for security vulnerabilities.
|
||||
|
||||
**Preferred:** email the maintainer at **jatinkrmalik@gmail.com** with subject:
|
||||
|
||||
`Vocalinux Security Vulnerability Report`
|
||||
`Voculinux Security Vulnerability Report`
|
||||
|
||||
Include:
|
||||
|
||||
@@ -35,7 +35,7 @@ If email is unavailable, use [GitHub private vulnerability reporting](https://gi
|
||||
|
||||
## Privacy design
|
||||
|
||||
Vocalinux is built for local-first dictation:
|
||||
Voculinux is built for local-first dictation:
|
||||
|
||||
- Local engines process audio on-device after you download a model
|
||||
- No Voca account is required for local engines
|
||||
@@ -62,8 +62,8 @@ When the user enables **Remote API**, audio is uploaded to the configured server
|
||||
|
||||
| Path | Purpose | Permissions (typical) |
|
||||
|------|---------|------------------------|
|
||||
| `~/.config/vocalinux/` | Configuration | User-only (mode 700) |
|
||||
| `~/.local/share/vocalinux/` | Data and models | User-only (mode 700) |
|
||||
| `~/.config/voculinux/` | Configuration | User-only (mode 700) |
|
||||
| `~/.local/share/voculinux/` | Data and models | User-only (mode 700) |
|
||||
|
||||
### Known limitations
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Support
|
||||
|
||||
Where to get help with Vocalinux.
|
||||
Where to get help with Voculinux.
|
||||
|
||||
## Documentation
|
||||
|
||||
@@ -14,7 +14,7 @@ Where to get help with Vocalinux.
|
||||
| Distros and sessions | [docs/DISTRO_COMPATIBILITY.md](docs/DISTRO_COMPATIBILITY.md) |
|
||||
| Remote transcription API | [docs/HTTP_REMOTE.md](docs/HTTP_REMOTE.md) |
|
||||
| Full index | [docs/README.md](docs/README.md) |
|
||||
| Website | [vocalinux.com](https://vocalinux.com) |
|
||||
| Website | [voculinux.com](https://voculinux.com) |
|
||||
|
||||
## Community
|
||||
|
||||
@@ -25,7 +25,7 @@ Where to get help with Vocalinux.
|
||||
| [Bug report](https://github.com/VocaHQ/vocalinux/issues/new?template=bug_report.md) | Something is broken |
|
||||
| [Feature request](https://github.com/VocaHQ/vocalinux/issues/new?template=feature_request.md) | New capability proposals |
|
||||
|
||||
When filing a bug, include OS/distro, `vocalinux --version`, install method, display server (X11/Wayland), engine, and a `vocalinux --debug` snippet.
|
||||
When filing a bug, include OS/distro, `voculinux --version`, install method, display server (X11/Wayland), engine, and a `voculinux --debug` snippet.
|
||||
|
||||
## Security
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'`**
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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`
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
description = "Vocalinux — free, offline voice dictation for Linux";
|
||||
description = "Voculinux — free, offline voice dictation for Linux";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
@@ -21,40 +21,40 @@
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
in
|
||||
{
|
||||
vocalinux = pkgs.python3Packages.callPackage ./packaging/nix/package.nix {
|
||||
voculinux = pkgs.python3Packages.callPackage ./packaging/nix/package.nix {
|
||||
pywhispercpp = pkgs.python3Packages.callPackage ./packaging/nix/pywhispercpp.nix { };
|
||||
src = self;
|
||||
};
|
||||
default = self.packages.${system}.vocalinux;
|
||||
default = self.packages.${system}.voculinux;
|
||||
}
|
||||
);
|
||||
|
||||
apps = forAllSystems (system: {
|
||||
vocalinux = {
|
||||
voculinux = {
|
||||
type = "app";
|
||||
program = "${self.packages.${system}.vocalinux}/bin/vocalinux";
|
||||
program = "${self.packages.${system}.voculinux}/bin/voculinux";
|
||||
};
|
||||
default = self.apps.${system}.vocalinux;
|
||||
default = self.apps.${system}.voculinux;
|
||||
});
|
||||
|
||||
overlays.default = final: prev: {
|
||||
vocalinux = self.packages.${prev.stdenv.hostPlatform.system}.vocalinux;
|
||||
voculinux = self.packages.${prev.stdenv.hostPlatform.system}.voculinux;
|
||||
};
|
||||
|
||||
nixosModules.vocalinux =
|
||||
nixosModules.voculinux =
|
||||
{ pkgs, lib, ... }:
|
||||
{
|
||||
imports = [ ./packaging/nix/module.nix ];
|
||||
programs.vocalinux.package = lib.mkDefault self.packages.${pkgs.stdenv.hostPlatform.system}.vocalinux;
|
||||
programs.voculinux.package = lib.mkDefault self.packages.${pkgs.stdenv.hostPlatform.system}.voculinux;
|
||||
};
|
||||
nixosModules.default = self.nixosModules.vocalinux;
|
||||
nixosModules.default = self.nixosModules.voculinux;
|
||||
|
||||
homeManagerModules.vocalinux =
|
||||
homeManagerModules.voculinux =
|
||||
{ pkgs, lib, ... }:
|
||||
{
|
||||
imports = [ ./packaging/nix/home-manager.nix ];
|
||||
programs.vocalinux.package = lib.mkDefault self.packages.${pkgs.stdenv.hostPlatform.system}.vocalinux;
|
||||
programs.voculinux.package = lib.mkDefault self.packages.${pkgs.stdenv.hostPlatform.system}.voculinux;
|
||||
};
|
||||
homeManagerModules.default = self.homeManagerModules.vocalinux;
|
||||
homeManagerModules.default = self.homeManagerModules.voculinux;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ install_desktop_entry() {
|
||||
print_info "Installing desktop entry..."
|
||||
|
||||
# Check if desktop entry file exists
|
||||
if [ ! -f "vocalinux.desktop" ]; then
|
||||
print_error "Desktop entry file not found: vocalinux.desktop"
|
||||
if [ ! -f "voculinux.desktop" ]; then
|
||||
print_error "Desktop entry file not found: voculinux.desktop"
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -19,27 +19,27 @@ install_desktop_entry() {
|
||||
}
|
||||
|
||||
# Copy desktop entry
|
||||
cp vocalinux.desktop "$DESKTOP_DIR/" || {
|
||||
cp voculinux.desktop "$DESKTOP_DIR/" || {
|
||||
print_error "Failed to copy desktop entry to $DESKTOP_DIR"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Update the desktop entry to use the wrapper script with GI_TYPELIB_PATH
|
||||
WRAPPER_SCRIPT="$HOME/.local/bin/vocalinux-gui"
|
||||
WRAPPER_SCRIPT="$HOME/.local/bin/voculinux-gui"
|
||||
if [ ! -f "$WRAPPER_SCRIPT" ]; then
|
||||
print_warning "Wrapper script not found at $WRAPPER_SCRIPT"
|
||||
print_warning "Desktop entry may not work correctly"
|
||||
else
|
||||
# Update Exec line to include GI_TYPELIB_PATH for PyGObject
|
||||
# Use the detected path for cross-distro compatibility
|
||||
sed -i "s|^Exec=vocalinux|Exec=env GI_TYPELIB_PATH=$GI_TYPELIB_DETECTED $WRAPPER_SCRIPT|" "$DESKTOP_DIR/vocalinux.desktop" || {
|
||||
sed -i "s|^Exec=voculinux|Exec=env GI_TYPELIB_PATH=$GI_TYPELIB_DETECTED $WRAPPER_SCRIPT|" "$DESKTOP_DIR/voculinux.desktop" || {
|
||||
print_warning "Failed to update desktop entry path"
|
||||
}
|
||||
print_info "Updated desktop entry to use wrapper script with GI_TYPELIB_PATH"
|
||||
fi
|
||||
|
||||
# Make desktop entry executable
|
||||
chmod +x "$DESKTOP_DIR/vocalinux.desktop" || {
|
||||
chmod +x "$DESKTOP_DIR/voculinux.desktop" || {
|
||||
print_warning "Failed to make desktop entry executable"
|
||||
}
|
||||
|
||||
@@ -64,10 +64,10 @@ install_icons() {
|
||||
|
||||
# List of icons to install
|
||||
local ICONS=(
|
||||
"vocalinux.svg"
|
||||
"vocalinux-microphone.svg"
|
||||
"vocalinux-microphone-off.svg"
|
||||
"vocalinux-microphone-process.svg"
|
||||
"voculinux.svg"
|
||||
"voculinux-microphone.svg"
|
||||
"voculinux-microphone-off.svg"
|
||||
"voculinux-microphone-process.svg"
|
||||
)
|
||||
|
||||
# Install each icon
|
||||
@@ -85,10 +85,10 @@ install_icons() {
|
||||
done
|
||||
|
||||
if [ "$INSTALLED_COUNT" -eq "${#ICONS[@]}" ]; then
|
||||
print_success "Installed all custom Vocalinux icons"
|
||||
print_success "Installed all custom Voculinux icons"
|
||||
return 0
|
||||
elif [ "$INSTALLED_COUNT" -gt 0 ]; then
|
||||
print_warning "Installed $INSTALLED_COUNT/${#ICONS[@]} custom Vocalinux icons"
|
||||
print_warning "Installed $INSTALLED_COUNT/${#ICONS[@]} custom Voculinux icons"
|
||||
return 0
|
||||
else
|
||||
print_error "Failed to install any icons"
|
||||
@@ -125,8 +125,8 @@ update_icon_cache() {
|
||||
install_resources_to_venv() {
|
||||
print_info "Installing resources to virtual environment..."
|
||||
|
||||
# Target directory: $VENV_DIR/share/vocalinux/resources
|
||||
local VENV_RESOURCES_DIR="$VENV_DIR/share/vocalinux/resources"
|
||||
# Target directory: $VENV_DIR/share/voculinux/resources
|
||||
local VENV_RESOURCES_DIR="$VENV_DIR/share/voculinux/resources"
|
||||
|
||||
# Create directories
|
||||
mkdir -p "$VENV_RESOURCES_DIR/icons/scalable" || {
|
||||
|
||||
@@ -27,7 +27,7 @@ run_interactive_install() {
|
||||
|
||||
EOF
|
||||
|
||||
echo "Welcome! This guided installation will help you set up Vocalinux"
|
||||
echo "Welcome! This guided installation will help you set up Voculinux"
|
||||
echo "with the best options for your system."
|
||||
echo ""
|
||||
echo "Local engines (whisper.cpp, Whisper, Faster Whisper, VOSK) process audio on-device after you download a model."
|
||||
@@ -38,11 +38,11 @@ EOF
|
||||
# and update in place instead of redoing first-time setup. Choosing the full
|
||||
# guided setup continues below and can re-point the engine deliberately.
|
||||
if [[ "${EXISTING_INSTALL:-no}" == "yes" ]]; then
|
||||
echo "An existing Vocalinux installation was detected:"
|
||||
echo "An existing Voculinux installation was detected:"
|
||||
echo " Configuration: $CONFIG_DIR/config.json (kept unchanged by an upgrade)"
|
||||
echo " Virtual env: $VENV_DIR (reused by an upgrade)"
|
||||
echo ""
|
||||
echo " 1. Upgrade (keep current settings) - update Vocalinux only"
|
||||
echo " 1. Upgrade (keep current settings) - update Voculinux only"
|
||||
echo " 2. Full guided setup - choose engine, backend, and model options"
|
||||
echo ""
|
||||
|
||||
@@ -330,7 +330,7 @@ EOF
|
||||
echo " Remote Server: $REMOTE_DISPLAY"
|
||||
fi
|
||||
echo " Models: $MODELS_DISPLAY"
|
||||
echo " Install Location: ${INSTALL_DIR:-\$HOME/.local/share/vocalinux}"
|
||||
echo " Install Location: ${INSTALL_DIR:-\$HOME/.local/share/voculinux}"
|
||||
echo ""
|
||||
read_prompt -p "Press Enter to continue with installation, or Ctrl+C to cancel..."
|
||||
echo ""
|
||||
|
||||
@@ -191,7 +191,7 @@ install_whisper_model() {
|
||||
print_info "Downloading Whisper tiny model..."
|
||||
print_info "This may take a few minutes depending on your internet connection."
|
||||
|
||||
local TEMP_FILE="$VOCALINUX_TMP_DIR/tiny.pt"
|
||||
local TEMP_FILE="$VOCULINUX_TMP_DIR/tiny.pt"
|
||||
|
||||
if ! download_model_file "$TINY_MODEL_URL" "$TEMP_FILE" "Whisper model"; then
|
||||
return 1
|
||||
@@ -214,7 +214,7 @@ install_whisper_model() {
|
||||
print_success "Whisper tiny model installed successfully ($MODEL_SIZE)"
|
||||
|
||||
# Create a marker file to indicate this model was pre-installed
|
||||
echo "$(date)" > "$WHISPER_DIR/.vocalinux_preinstalled"
|
||||
echo "$(date)" > "$WHISPER_DIR/.voculinux_preinstalled"
|
||||
|
||||
return 0
|
||||
else
|
||||
@@ -241,7 +241,7 @@ install_vosk_models() {
|
||||
# is deleted after unpacking. So whoever unpacks it records the verified zip
|
||||
# digest in a stamp (here, and in the app's own downloader), and the directory
|
||||
# is trusted only while that stamp matches what we pin today.
|
||||
local SMALL_MODEL_STAMP="$SMALL_MODEL_PATH/.vocalinux_verified"
|
||||
local SMALL_MODEL_STAMP="$SMALL_MODEL_PATH/.voculinux_verified"
|
||||
local EXPECTED_ZIP_DIGEST
|
||||
EXPECTED_ZIP_DIGEST=$(pinned_digest_for "$SMALL_MODEL_ARCHIVE" || true)
|
||||
if [ -d "$SMALL_MODEL_PATH" ]; then
|
||||
@@ -282,7 +282,7 @@ install_vosk_models() {
|
||||
print_info "Downloading small VOSK model (approximately 40MB)..."
|
||||
print_info "This may take a few minutes depending on your internet connection."
|
||||
|
||||
local TEMP_ZIP="$VOCALINUX_TMP_DIR/$(basename $SMALL_MODEL_URL)"
|
||||
local TEMP_ZIP="$VOCULINUX_TMP_DIR/$(basename $SMALL_MODEL_URL)"
|
||||
|
||||
if ! download_model_file "$SMALL_MODEL_URL" "$TEMP_ZIP" "VOSK model"; then
|
||||
return 1
|
||||
@@ -334,13 +334,13 @@ install_vosk_models() {
|
||||
fi
|
||||
|
||||
chmod -R 755 "$STAGING_DIR/$SMALL_MODEL_NAME"
|
||||
echo "$(date)" > "$STAGING_DIR/$SMALL_MODEL_NAME/.vocalinux_preinstalled"
|
||||
echo "$(date)" > "$STAGING_DIR/$SMALL_MODEL_NAME/.voculinux_preinstalled"
|
||||
|
||||
# Record the digest this tree was extracted from, so a later run can tell a
|
||||
# verified model from one that merely exists. Written before the swap: an
|
||||
# unstamped tree is one this function would download all over again.
|
||||
if [ -z "$EXPECTED_ZIP_DIGEST" ] ||
|
||||
! printf '%s\n' "$EXPECTED_ZIP_DIGEST" > "$STAGING_DIR/$SMALL_MODEL_NAME/.vocalinux_verified"; then
|
||||
! printf '%s\n' "$EXPECTED_ZIP_DIGEST" > "$STAGING_DIR/$SMALL_MODEL_NAME/.voculinux_verified"; then
|
||||
print_error "Could not record the verified digest for $SMALL_MODEL_NAME"
|
||||
rm -rf "$STAGING_DIR"
|
||||
return 1
|
||||
@@ -418,7 +418,7 @@ install_whispercpp_model() {
|
||||
print_info "Downloading whisper.cpp tiny model..."
|
||||
print_info "This may take a few minutes depending on your internet connection."
|
||||
|
||||
local TEMP_FILE="$VOCALINUX_TMP_DIR/ggml-tiny.bin"
|
||||
local TEMP_FILE="$VOCULINUX_TMP_DIR/ggml-tiny.bin"
|
||||
|
||||
if ! download_model_file "$TINY_MODEL_URL" "$TEMP_FILE" "whisper.cpp model"; then
|
||||
return 1
|
||||
@@ -441,7 +441,7 @@ install_whispercpp_model() {
|
||||
print_success "whisper.cpp tiny model installed successfully ($MODEL_SIZE)"
|
||||
|
||||
# Create a marker file to indicate this model was pre-installed
|
||||
echo "$(date)" > "$WHISPERCPP_DIR/.vocalinux_preinstalled"
|
||||
echo "$(date)" > "$WHISPERCPP_DIR/.voculinux_preinstalled"
|
||||
|
||||
return 0
|
||||
else
|
||||
|
||||
@@ -565,7 +565,7 @@ install_system_dependencies() {
|
||||
print_error "Unsupported distribution family: $DISTRO_FAMILY"
|
||||
print_info ""
|
||||
print_info "Your distribution ($DISTRO_NAME) is not officially supported."
|
||||
print_info "However, you can still install Vocalinux manually:"
|
||||
print_info "However, you can still install Voculinux manually:"
|
||||
print_info ""
|
||||
print_info "1. Run the dependency checker:"
|
||||
print_info " bash scripts/check-system-deps.sh"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
# Vocalinux Installer
|
||||
# This script installs the Vocalinux application and its dependencies
|
||||
# Voculinux Installer
|
||||
# This script installs the Voculinux application and its dependencies
|
||||
|
||||
# -E: ERR trap propagates into functions/subshells
|
||||
# -e: exit on unhandled command failure -u: error on unset variables
|
||||
@@ -118,7 +118,7 @@ is_kde_plasma_session() {
|
||||
print_kde_wayland_ibus_hint() {
|
||||
print_warning "KDE Plasma Wayland detected."
|
||||
print_info "For direct dictation into apps, open System Settings -> Keyboard -> Virtual Keyboard and select 'IBus Wayland'."
|
||||
print_info "After changing it, restart Vocalinux or log out and back in."
|
||||
print_info "After changing it, restart Voculinux or log out and back in."
|
||||
}
|
||||
|
||||
# Read a numeric PID from a file (instance.lock / engine.pid). Empty if missing/invalid.
|
||||
@@ -133,9 +133,9 @@ read_pid_file() {
|
||||
fi
|
||||
}
|
||||
|
||||
# True only for the Vocalinux app / IBus engine — not editors, shells, or tests
|
||||
# whose argv merely contains the string "vocalinux" (e.g. cwd under the repo).
|
||||
is_vocalinux_process() {
|
||||
# True only for the Voculinux app / IBus engine — not editors, shells, or tests
|
||||
# whose argv merely contains the string "voculinux" (e.g. cwd under the repo).
|
||||
is_voculinux_process() {
|
||||
local pid="$1"
|
||||
|
||||
if [ "$pid" = "$$" ] || [ "$pid" = "$PPID" ]; then
|
||||
@@ -163,18 +163,18 @@ is_vocalinux_process() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
# IBus engine: .../vocalinux/.../ibus_engine.py
|
||||
if [[ "$cmdline" == *"ibus_engine.py"* && "$cmdline" == *"vocalinux"* ]]; then
|
||||
# IBus engine: .../voculinux/.../ibus_engine.py
|
||||
if [[ "$cmdline" == *"ibus_engine.py"* && "$cmdline" == *"voculinux"* ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Console-script entrypoints. Setuptools scripts are executed as
|
||||
# `python …/bin/vocalinux`, so argv0 is python — scan every arg for the
|
||||
# script path (require …/bin/vocalinux to avoid matching a repo directory).
|
||||
# `python …/bin/voculinux`, so argv0 is python — scan every arg for the
|
||||
# script path (require …/bin/voculinux to avoid matching a repo directory).
|
||||
local arg
|
||||
while IFS= read -r -d '' arg; do
|
||||
case "$arg" in
|
||||
vocalinux|vocalinux-gui|*/bin/vocalinux|*/bin/vocalinux-gui)
|
||||
voculinux|voculinux-gui|*/bin/voculinux|*/bin/voculinux-gui)
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
@@ -184,16 +184,16 @@ is_vocalinux_process() {
|
||||
}
|
||||
|
||||
# Prefer the PIDs the app writes; fall back to narrow entrypoint patterns only.
|
||||
# Deliberately does NOT use `pgrep -f vocalinux` (matches editors/shells/cwd paths).
|
||||
get_vocalinux_pids() {
|
||||
# Deliberately does NOT use `pgrep -f voculinux` (matches editors/shells/cwd paths).
|
||||
get_voculinux_pids() {
|
||||
local data_home="${XDG_DATA_HOME:-$HOME/.local/share}"
|
||||
local -A seen=()
|
||||
local pid candidate
|
||||
local -a candidates=()
|
||||
|
||||
for candidate in \
|
||||
"$(read_pid_file "$data_home/vocalinux/instance.lock")" \
|
||||
"$(read_pid_file "$data_home/vocalinux-ibus/engine.pid")"
|
||||
"$(read_pid_file "$data_home/voculinux/instance.lock")" \
|
||||
"$(read_pid_file "$data_home/voculinux-ibus/engine.pid")"
|
||||
do
|
||||
[ -n "$candidate" ] && candidates+=("$candidate")
|
||||
done
|
||||
@@ -202,16 +202,16 @@ get_vocalinux_pids() {
|
||||
while read -r candidate; do
|
||||
[ -n "$candidate" ] && candidates+=("$candidate")
|
||||
done < <(
|
||||
pgrep -u "$(id -u)" -x vocalinux 2>/dev/null || true
|
||||
pgrep -u "$(id -u)" -x vocalinux-gui 2>/dev/null || true
|
||||
pgrep -u "$(id -u)" -f -- '-m vocalinux\.main' 2>/dev/null || true
|
||||
pgrep -u "$(id -u)" -f -- 'vocalinux/.*/ibus_engine\.py' 2>/dev/null || true
|
||||
pgrep -u "$(id -u)" -x voculinux 2>/dev/null || true
|
||||
pgrep -u "$(id -u)" -x voculinux-gui 2>/dev/null || true
|
||||
pgrep -u "$(id -u)" -f -- '-m voculinux\.main' 2>/dev/null || true
|
||||
pgrep -u "$(id -u)" -f -- 'voculinux/.*/ibus_engine\.py' 2>/dev/null || true
|
||||
)
|
||||
|
||||
for pid in "${candidates[@]}"; do
|
||||
[ -n "${seen[$pid]:-}" ] && continue
|
||||
seen[$pid]=1
|
||||
if is_vocalinux_process "$pid"; then
|
||||
if is_voculinux_process "$pid"; then
|
||||
echo "$pid"
|
||||
fi
|
||||
done
|
||||
@@ -219,10 +219,10 @@ get_vocalinux_pids() {
|
||||
|
||||
check_running_processes() {
|
||||
local PIDS
|
||||
PIDS=$(get_vocalinux_pids || true)
|
||||
PIDS=$(get_voculinux_pids || true)
|
||||
|
||||
if [ -n "$PIDS" ]; then
|
||||
print_warning "Found running Vocalinux process(es):"
|
||||
print_warning "Found running Voculinux process(es):"
|
||||
local pid
|
||||
for pid in $PIDS; do
|
||||
local cmd
|
||||
@@ -232,24 +232,24 @@ check_running_processes() {
|
||||
echo ""
|
||||
|
||||
if [[ "$NON_INTERACTIVE" == "yes" ]]; then
|
||||
print_info "Non-interactive mode: stopping Vocalinux automatically..."
|
||||
print_info "Non-interactive mode: stopping Voculinux automatically..."
|
||||
else
|
||||
read_prompt -p "Vocalinux must be stopped before installation. Kill running process(es)? (Y/n) " -n 1 -r
|
||||
read_prompt -p "Voculinux must be stopped before installation. Kill running process(es)? (Y/n) " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Nn]$ ]]; then
|
||||
print_error "Cannot proceed with installation while Vocalinux is running."
|
||||
print_info "Please stop Vocalinux manually and run the installer again."
|
||||
print_error "Cannot proceed with installation while Voculinux is running."
|
||||
print_info "Please stop Voculinux manually and run the installer again."
|
||||
exit "$EXIT_USER_ABORT"
|
||||
fi
|
||||
fi
|
||||
|
||||
print_info "Stopping Vocalinux..."
|
||||
print_info "Stopping Voculinux..."
|
||||
# shellcheck disable=SC2086
|
||||
echo $PIDS | xargs -r kill -TERM 2>/dev/null || true
|
||||
sleep 2
|
||||
|
||||
local REMAINING_PIDS
|
||||
REMAINING_PIDS=$(get_vocalinux_pids || true)
|
||||
REMAINING_PIDS=$(get_voculinux_pids || true)
|
||||
|
||||
if [ -n "$REMAINING_PIDS" ]; then
|
||||
print_warning "Some processes still running, forcing termination..."
|
||||
@@ -259,13 +259,13 @@ check_running_processes() {
|
||||
fi
|
||||
|
||||
local FINAL_PIDS
|
||||
FINAL_PIDS=$(get_vocalinux_pids || true)
|
||||
FINAL_PIDS=$(get_voculinux_pids || true)
|
||||
if [ -n "$FINAL_PIDS" ]; then
|
||||
print_error "Could not terminate all Vocalinux processes: $FINAL_PIDS"
|
||||
print_error "Could not terminate all Voculinux processes: $FINAL_PIDS"
|
||||
print_error "Please manually kill these processes and run the installer again."
|
||||
exit "$EXIT_USER_ABORT"
|
||||
else
|
||||
print_success "All Vocalinux processes stopped"
|
||||
print_success "All Voculinux processes stopped"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
@@ -373,7 +373,7 @@ while [[ $# -gt 0 ]]; do
|
||||
shift
|
||||
;;
|
||||
--help)
|
||||
echo "Vocalinux Installer"
|
||||
echo "Voculinux Installer"
|
||||
echo ""
|
||||
echo "Usage: $0 [options]"
|
||||
echo ""
|
||||
@@ -410,7 +410,7 @@ while [[ $# -gt 0 ]]; do
|
||||
echo " $0 --dev --test # Dev mode with tests"
|
||||
echo ""
|
||||
echo "During installation a full transcript is saved to"
|
||||
echo " ~/.local/state/vocalinux/install-<timestamp>.log"
|
||||
echo " ~/.local/state/voculinux/install-<timestamp>.log"
|
||||
echo ""
|
||||
echo "Exit codes:"
|
||||
echo " 0 success"
|
||||
@@ -437,7 +437,7 @@ fi
|
||||
# Global install log: everything (stdout + stderr) is teed to this file so
|
||||
# failures can be debugged after the fact. The path is printed at exit.
|
||||
# ---------------------------------------------------------------------------
|
||||
INSTALL_LOG_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/vocalinux"
|
||||
INSTALL_LOG_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/voculinux"
|
||||
if ! mkdir -p "$INSTALL_LOG_DIR" 2>/dev/null; then
|
||||
INSTALL_LOG_DIR="${TMPDIR:-/tmp}"
|
||||
fi
|
||||
@@ -447,18 +447,18 @@ exec > >(tee -a "$INSTALL_LOG_FILE") 2>&1
|
||||
# Scratch directory for pip logs, model downloads, and other temps.
|
||||
# Removed on success; kept for inspection (with a notice) when the install fails.
|
||||
# Exporting TMPDIR routes pip/wget/curl scratch files into this directory.
|
||||
VOCALINUX_TMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/vocalinux-install.XXXXXXXX")"
|
||||
export TMPDIR="$VOCALINUX_TMP_DIR"
|
||||
VOCULINUX_TMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/voculinux-install.XXXXXXXX")"
|
||||
export TMPDIR="$VOCULINUX_TMP_DIR"
|
||||
|
||||
cleanup_on_exit() {
|
||||
local rc=$?
|
||||
if [ "$rc" -eq "$EXIT_OK" ]; then
|
||||
rm -rf "$VOCALINUX_TMP_DIR"
|
||||
rm -rf "$VOCULINUX_TMP_DIR"
|
||||
else
|
||||
print_error ""
|
||||
print_error "Installation did not complete (exit code $rc)."
|
||||
print_error "Full install log: $INSTALL_LOG_FILE"
|
||||
print_error "Scratch files kept for inspection: $VOCALINUX_TMP_DIR"
|
||||
print_error "Scratch files kept for inspection: $VOCULINUX_TMP_DIR"
|
||||
fi
|
||||
}
|
||||
trap cleanup_on_exit EXIT
|
||||
@@ -478,7 +478,7 @@ cat << "EOF"
|
||||
|
||||
EOF
|
||||
|
||||
print_info "Vocalinux Installer"
|
||||
print_info "Voculinux Installer"
|
||||
print_info "=============================="
|
||||
echo ""
|
||||
|
||||
@@ -509,21 +509,21 @@ resolve_install_tag() {
|
||||
|
||||
resolve_install_tag
|
||||
|
||||
# Check if running from within the vocalinux repo or remotely (via curl)
|
||||
# VOCALINUX_REPO_URL overrides the clone source so the remote-install gate can
|
||||
# Check if running from within the voculinux repo or remotely (via curl)
|
||||
# VOCULINUX_REPO_URL overrides the clone source so the remote-install gate can
|
||||
# serve a tag from a local mirror; public installs use the repository below.
|
||||
REPO_URL="${VOCALINUX_REPO_URL:-https://github.com/VocaHQ/vocalinux.git}"
|
||||
REPO_URL="${VOCULINUX_REPO_URL:-https://github.com/VocaHQ/vocalinux.git}"
|
||||
INSTALL_DIR=""
|
||||
CLEANUP_ON_EXIT="${VOCALINUX_REMOTE_INSTALL:-no}"
|
||||
CLEANUP_ON_EXIT="${VOCULINUX_REMOTE_INSTALL:-no}"
|
||||
|
||||
handoff_to_tagged_installer() {
|
||||
local tagged_installer="$INSTALL_DIR/install.sh"
|
||||
local remote_venv="$HOME/.local/share/vocalinux/venv"
|
||||
local remote_venv="$HOME/.local/share/voculinux/venv"
|
||||
|
||||
if grep -q 'CLEANUP_ON_EXIT="${VOCALINUX_REMOTE_INSTALL:-no}"' "$tagged_installer"; then
|
||||
export VOCALINUX_REMOTE_INSTALL=yes
|
||||
export TMPDIR="$(dirname "$VOCALINUX_TMP_DIR")"
|
||||
rmdir "$VOCALINUX_TMP_DIR"
|
||||
if grep -q 'CLEANUP_ON_EXIT="${VOCULINUX_REMOTE_INSTALL:-no}"' "$tagged_installer"; then
|
||||
export VOCULINUX_REMOTE_INSTALL=yes
|
||||
export TMPDIR="$(dirname "$VOCULINUX_TMP_DIR")"
|
||||
rmdir "$VOCULINUX_TMP_DIR"
|
||||
# A bootstrap read from a pipe (curl | bash) leaves its unread tail on
|
||||
# stdin: bash hands the pipe to the tagged installer, which reads its
|
||||
# commands from a file instead, so nothing drains it. A producer still
|
||||
@@ -537,12 +537,12 @@ handoff_to_tagged_installer() {
|
||||
fi
|
||||
|
||||
bash "$tagged_installer" "${INSTALLER_ARGS[@]}" "--venv-dir=$remote_venv" || return $?
|
||||
if [ ! -f "$INSTALL_DIR/activate-vocalinux.sh" ]; then
|
||||
print_error "The tagged installer did not create activate-vocalinux.sh."
|
||||
if [ ! -f "$INSTALL_DIR/activate-voculinux.sh" ]; then
|
||||
print_error "The tagged installer did not create activate-voculinux.sh."
|
||||
return 1
|
||||
fi
|
||||
mkdir -p "$HOME/.local/bin"
|
||||
mv "$INSTALL_DIR/activate-vocalinux.sh" "$HOME/.local/bin/activate-vocalinux.sh"
|
||||
mv "$INSTALL_DIR/activate-voculinux.sh" "$HOME/.local/bin/activate-voculinux.sh"
|
||||
}
|
||||
|
||||
# Function to check and install git if needed
|
||||
@@ -664,17 +664,17 @@ ensure_git_installed() {
|
||||
print_success "git installed successfully!"
|
||||
}
|
||||
|
||||
# Check if running from within the vocalinux repository
|
||||
# Validate that pyproject.toml/setup.py actually belongs to vocalinux before entering local repo mode
|
||||
IS_VOCALINUX_LOCAL=false
|
||||
if [ -f "pyproject.toml" ] && grep -q 'name = "vocalinux"' "pyproject.toml" 2>/dev/null; then
|
||||
IS_VOCALINUX_LOCAL=true
|
||||
elif [ -f "setup.py" ] && grep -q "vocalinux" "setup.py" 2>/dev/null; then
|
||||
IS_VOCALINUX_LOCAL=true
|
||||
# Check if running from within the voculinux repository
|
||||
# Validate that pyproject.toml/setup.py actually belongs to voculinux before entering local repo mode
|
||||
IS_VOCULINUX_LOCAL=false
|
||||
if [ -f "pyproject.toml" ] && grep -q 'name = "voculinux"' "pyproject.toml" 2>/dev/null; then
|
||||
IS_VOCULINUX_LOCAL=true
|
||||
elif [ -f "setup.py" ] && grep -q "voculinux" "setup.py" 2>/dev/null; then
|
||||
IS_VOCULINUX_LOCAL=true
|
||||
fi
|
||||
|
||||
if [ "$IS_VOCALINUX_LOCAL" = true ]; then
|
||||
# Running from within the vocalinux repo
|
||||
if [ "$IS_VOCULINUX_LOCAL" = true ]; then
|
||||
# Running from within the voculinux repo
|
||||
INSTALL_DIR="$(pwd)"
|
||||
print_info "Running from local repository: $INSTALL_DIR"
|
||||
# Convert relative VENV_DIR to absolute for wrapper scripts.
|
||||
@@ -690,26 +690,26 @@ else
|
||||
print_error "Re-run with an explicit release tag, e.g.: --tag=<release>"
|
||||
exit "$EXIT_NETWORK"
|
||||
fi
|
||||
print_info "Installing Vocalinux version: ${INSTALL_TAG}"
|
||||
print_info "Installing Voculinux version: ${INSTALL_TAG}"
|
||||
|
||||
# Ensure git is installed before attempting to clone
|
||||
ensure_git_installed
|
||||
|
||||
INSTALL_DIR="$HOME/.local/share/vocalinux-install"
|
||||
INSTALL_DIR="$HOME/.local/share/voculinux-install"
|
||||
mkdir -p "$INSTALL_DIR"
|
||||
|
||||
if [ -d "$INSTALL_DIR/.git" ]; then
|
||||
print_info "Updating existing clone..."
|
||||
cd "$INSTALL_DIR"
|
||||
if ! git fetch origin tag "$INSTALL_TAG" || ! git reset --hard "$INSTALL_TAG"; then
|
||||
print_error "Failed to update the Vocalinux clone to $INSTALL_TAG."
|
||||
print_error "Failed to update the Voculinux clone to $INSTALL_TAG."
|
||||
print_error "Check the install log and your network connection: $INSTALL_LOG_FILE"
|
||||
exit "$EXIT_NETWORK"
|
||||
fi
|
||||
else
|
||||
rm -rf "$INSTALL_DIR"
|
||||
git clone --depth 1 --branch "$INSTALL_TAG" "$REPO_URL" "$INSTALL_DIR" || {
|
||||
print_error "Failed to clone Vocalinux repository"
|
||||
print_error "Failed to clone Voculinux repository"
|
||||
exit "$EXIT_NETWORK"
|
||||
}
|
||||
cd "$INSTALL_DIR"
|
||||
@@ -1270,7 +1270,7 @@ detect_distro
|
||||
|
||||
# Check compatibility. These tiers mirror docs/DISTRO_COMPATIBILITY.md, and the
|
||||
# distro matrix builds on ubuntu, debian and fedora. Nothing here decides whether
|
||||
# the install can proceed: what Vocalinux needs is an interpreter at the floor
|
||||
# the install can proceed: what Voculinux needs is an interpreter at the floor
|
||||
# and that interpreter's distro PyGObject, checked by check_python_version()
|
||||
# (fatal) and require_distro_gi() further down. This block only says how much
|
||||
# help the package step is likely to be, so it must not turn away a distro the
|
||||
@@ -1286,7 +1286,7 @@ case "$DISTRO_FAMILY" in
|
||||
;;
|
||||
*)
|
||||
print_warning "This installer has not been tested on $DISTRO_NAME; you may need to install dependencies manually."
|
||||
print_warning "Vocalinux itself does not care which distribution it runs on, only that Python and PyGObject are new enough."
|
||||
print_warning "Voculinux itself does not care which distribution it runs on, only that Python and PyGObject are new enough."
|
||||
if [[ "$NON_INTERACTIVE" == "yes" ]]; then
|
||||
print_info "Non-interactive mode: continuing anyway..."
|
||||
else
|
||||
@@ -1301,8 +1301,8 @@ esac
|
||||
|
||||
# Define XDG directories early: existing-install detection and the mode menu
|
||||
# need CONFIG_DIR before system dependency installation asks anything.
|
||||
CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/vocalinux"
|
||||
DATA_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/vocalinux"
|
||||
CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/voculinux"
|
||||
DATA_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/voculinux"
|
||||
DESKTOP_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/applications"
|
||||
ICON_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/icons/hicolor/scalable/apps"
|
||||
|
||||
@@ -1322,7 +1322,7 @@ choose_installation_mode() {
|
||||
echo ""
|
||||
echo "Installation Mode:"
|
||||
if [[ "${EXISTING_INSTALL:-no}" == "yes" ]]; then
|
||||
echo " 1. Upgrade (keep current settings) - update Vocalinux, keep your setup"
|
||||
echo " 1. Upgrade (keep current settings) - update Voculinux, keep your setup"
|
||||
echo " 2. Interactive - guided setup with recommendations"
|
||||
echo " 3. Automatic - quick install with defaults (whisper.cpp)"
|
||||
echo ""
|
||||
@@ -1653,7 +1653,7 @@ install_pinned_build_tools() {
|
||||
print_info "Installing pinned pip and source-build tools..."
|
||||
"$VENV_DIR/bin/python" -m pip install --require-hashes --no-deps \
|
||||
--only-binary=:all: --ignore-installed \
|
||||
-r "$reqs_file" --log "$VOCALINUX_TMP_DIR/bootstrap.log"
|
||||
-r "$reqs_file" --log "$VOCULINUX_TMP_DIR/bootstrap.log"
|
||||
}
|
||||
install_pinned_build_tools || {
|
||||
print_error "Failed to install the pinned build tools. Check requirements/installer-build.txt."
|
||||
@@ -1668,15 +1668,15 @@ if [[ "$CLEANUP_ON_EXIT" == "yes" ]]; then
|
||||
else
|
||||
ACTIVATION_SCRIPT_DIR="."
|
||||
fi
|
||||
ACTIVATION_SCRIPT="$ACTIVATION_SCRIPT_DIR/activate-vocalinux.sh"
|
||||
ACTIVATION_SCRIPT="$ACTIVATION_SCRIPT_DIR/activate-voculinux.sh"
|
||||
|
||||
cat > "$ACTIVATION_SCRIPT" << EOF
|
||||
#!/bin/bash
|
||||
# This script activates the Vocalinux virtual environment
|
||||
# This script activates the Voculinux virtual environment
|
||||
export PYTHONNOUSERSITE=1
|
||||
source "$VENV_DIR/bin/activate"
|
||||
echo "Vocalinux virtual environment activated."
|
||||
echo "To start the application, run: vocalinux"
|
||||
echo "Voculinux virtual environment activated."
|
||||
echo "To start the application, run: voculinux"
|
||||
EOF
|
||||
chmod +x "$ACTIVATION_SCRIPT"
|
||||
print_info "Created activation script: $ACTIVATION_SCRIPT"
|
||||
@@ -1897,7 +1897,7 @@ install_cpu_pywhispercpp() {
|
||||
pip_reinstall_pywhispercpp() {
|
||||
local pip_log="$1"
|
||||
shift
|
||||
local reqs_file="$VOCALINUX_TMP_DIR/pywhispercpp.txt"
|
||||
local reqs_file="$VOCULINUX_TMP_DIR/pywhispercpp.txt"
|
||||
"$VENV_DIR/bin/python" "$INSTALL_DIR/scripts/installer_requirements.py" \
|
||||
"$INSTALL_DIR/requirements/runtime.txt" "$reqs_file" --package pywhispercpp || return 1
|
||||
# --no-deps preserves the locked runtime and avoids reinstalling numpy
|
||||
@@ -2190,7 +2190,7 @@ install_whispercpp_with_gpu_support() {
|
||||
fi
|
||||
|
||||
if ! is_pywhispercpp_installed; then
|
||||
print_warning "pywhispercpp is still unavailable; setting VOSK as the default engine so Vocalinux can start."
|
||||
print_warning "pywhispercpp is still unavailable; setting VOSK as the default engine so Voculinux can start."
|
||||
print_warning "You can switch back to whisper.cpp from Settings after reinstalling pywhispercpp."
|
||||
SELECTED_ENGINE="vosk"
|
||||
|
||||
@@ -2304,7 +2304,7 @@ pip_install_extras_skip_pygobject() {
|
||||
# Function to install Python package with error handling and verification
|
||||
install_python_package() {
|
||||
# Pip logs live in the install scratch dir so a failed run can keep them.
|
||||
local PIP_LOG_DIR="$VOCALINUX_TMP_DIR/pip"
|
||||
local PIP_LOG_DIR="$VOCULINUX_TMP_DIR/pip"
|
||||
mkdir -p "$PIP_LOG_DIR"
|
||||
local PIP_LOG_FILE="$PIP_LOG_DIR/pip_log.txt"
|
||||
|
||||
@@ -2351,21 +2351,21 @@ PY
|
||||
print_success "Neural VAD support installed and verified successfully."
|
||||
else
|
||||
print_warning "Neural VAD dependencies installed, but Silero VAD could not be verified."
|
||||
print_warning "Vocalinux will use amplitude-based VAD until this is resolved."
|
||||
print_warning "Voculinux will use amplitude-based VAD until this is resolved."
|
||||
fi
|
||||
else
|
||||
print_warning "Failed to install neural VAD support."
|
||||
print_warning "Vocalinux will still work using amplitude-based VAD."
|
||||
print_warning "Voculinux will still work using amplitude-based VAD."
|
||||
print_warning "Check the pip log for details: $PIP_LOG_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ "$DEV_MODE" == "yes" ]]; then
|
||||
print_info "Installing Vocalinux in development mode..."
|
||||
print_info "Installing Voculinux in development mode..."
|
||||
|
||||
# Install in development mode with logging
|
||||
pip_install_project_skip_pygobject "$PIP_LOG_FILE" -e . || {
|
||||
print_error "Failed to install Vocalinux in development mode."
|
||||
print_error "Failed to install Voculinux in development mode."
|
||||
print_error "Check the pip log for details: $PIP_LOG_FILE"
|
||||
return 1
|
||||
}
|
||||
@@ -2389,11 +2389,11 @@ PY
|
||||
install_whispercpp_with_gpu_support "$PIP_LOG_FILE"
|
||||
fi
|
||||
else
|
||||
print_info "Installing Vocalinux..."
|
||||
print_info "Installing Voculinux..."
|
||||
|
||||
# Install the package with logging (includes pywhispercpp by default)
|
||||
pip_install_project_skip_pygobject "$PIP_LOG_FILE" . || {
|
||||
print_error "Failed to install Vocalinux."
|
||||
print_error "Failed to install Voculinux."
|
||||
print_error "Check the pip log for details: $PIP_LOG_FILE"
|
||||
return 1
|
||||
}
|
||||
@@ -2701,8 +2701,8 @@ FASTER_WHISPER_CONFIG
|
||||
|
||||
# Verify installation
|
||||
if verify_package_installed; then
|
||||
print_success "Vocalinux package installed successfully!"
|
||||
# Pip logs stay under VOCALINUX_TMP_DIR; the EXIT trap removes that
|
||||
print_success "Voculinux package installed successfully!"
|
||||
# Pip logs stay under VOCULINUX_TMP_DIR; the EXIT trap removes that
|
||||
# directory on success and keeps it when a later step fails.
|
||||
|
||||
# GI_TYPELIB_PATH was already detected at the start of install_python_package
|
||||
@@ -2720,10 +2720,10 @@ else
|
||||
exec $EXEC_CMD
|
||||
fi'
|
||||
|
||||
# Create vocalinux wrapper script
|
||||
cat > "$HOME/.local/bin/vocalinux" << WRAPPER_EOF
|
||||
# Create voculinux wrapper script
|
||||
cat > "$HOME/.local/bin/voculinux" << WRAPPER_EOF
|
||||
#!/bin/bash
|
||||
# Wrapper script for Vocalinux that sets required environment variables
|
||||
# Wrapper script for Voculinux that sets required environment variables
|
||||
# and applies the 'input' group for keyboard shortcuts on Wayland
|
||||
export PYTHONNOUSERSITE=1
|
||||
export GI_TYPELIB_PATH=$GI_TYPELIB_DETECTED
|
||||
@@ -2754,16 +2754,16 @@ if [ -n "\$PYWHISPERCPP_LIBRARY_PATH" ]; then
|
||||
export LD_LIBRARY_PATH="\$PYWHISPERCPP_LIBRARY_PATH\${LD_LIBRARY_PATH:+:\$LD_LIBRARY_PATH}"
|
||||
fi
|
||||
|
||||
EXEC_CMD="$VENV_DIR/bin/vocalinux \$*"
|
||||
EXEC_CMD="$VENV_DIR/bin/voculinux \$*"
|
||||
$SG_CHECK
|
||||
WRAPPER_EOF
|
||||
chmod +x "$HOME/.local/bin/vocalinux"
|
||||
print_info "Created wrapper: ~/.local/bin/vocalinux"
|
||||
chmod +x "$HOME/.local/bin/voculinux"
|
||||
print_info "Created wrapper: ~/.local/bin/voculinux"
|
||||
|
||||
# Create vocalinux-gui wrapper script
|
||||
cat > "$HOME/.local/bin/vocalinux-gui" << WRAPPER_EOF
|
||||
# Create voculinux-gui wrapper script
|
||||
cat > "$HOME/.local/bin/voculinux-gui" << WRAPPER_EOF
|
||||
#!/bin/bash
|
||||
# Wrapper script for Vocalinux GUI that sets required environment variables
|
||||
# Wrapper script for Voculinux GUI that sets required environment variables
|
||||
# and applies the 'input' group for keyboard shortcuts on Wayland
|
||||
export PYTHONNOUSERSITE=1
|
||||
export GI_TYPELIB_PATH=$GI_TYPELIB_DETECTED
|
||||
@@ -2794,11 +2794,11 @@ if [ -n "\$PYWHISPERCPP_LIBRARY_PATH" ]; then
|
||||
export LD_LIBRARY_PATH="\$PYWHISPERCPP_LIBRARY_PATH\${LD_LIBRARY_PATH:+:\$LD_LIBRARY_PATH}"
|
||||
fi
|
||||
|
||||
EXEC_CMD="$VENV_DIR/bin/vocalinux-gui \$*"
|
||||
EXEC_CMD="$VENV_DIR/bin/voculinux-gui \$*"
|
||||
$SG_CHECK
|
||||
WRAPPER_EOF
|
||||
chmod +x "$HOME/.local/bin/vocalinux-gui"
|
||||
print_info "Created wrapper: ~/.local/bin/vocalinux-gui"
|
||||
chmod +x "$HOME/.local/bin/voculinux-gui"
|
||||
print_info "Created wrapper: ~/.local/bin/voculinux-gui"
|
||||
|
||||
# Check if ~/.local/bin is in PATH
|
||||
if [[ ":$PATH:" != *":$HOME/.local/bin:"* ]]; then
|
||||
@@ -2809,7 +2809,7 @@ WRAPPER_EOF
|
||||
|
||||
return 0
|
||||
else
|
||||
print_error "Vocalinux package installation verification failed."
|
||||
print_error "Voculinux package installation verification failed."
|
||||
print_error "Check the pip log for details: $PIP_LOG_FILE"
|
||||
return 1
|
||||
fi
|
||||
@@ -2817,7 +2817,7 @@ WRAPPER_EOF
|
||||
|
||||
# Install Python package
|
||||
if ! install_python_package; then
|
||||
print_error "Failed to install Vocalinux package. Installation cannot continue."
|
||||
print_error "Failed to install Voculinux package. Installation cannot continue."
|
||||
exit "$EXIT_NETWORK"
|
||||
fi
|
||||
|
||||
@@ -2907,7 +2907,7 @@ PY
|
||||
|
||||
if [[ "${UPGRADE_MODE:-no}" == "yes" ]]; then
|
||||
# Upgrade mode never rewrites config.json: report instead of repairing.
|
||||
print_error "Vocalinux cannot start with this configuration and the engine is not installed."
|
||||
print_error "Voculinux cannot start with this configuration and the engine is not installed."
|
||||
print_error "Install the engine: $VENV_DIR/bin/pip install $(engine_pip_name "$CONFIGURED_ENGINE")"
|
||||
print_error "or edit $CONFIG_FILE and set speech_recognition.engine to an installed engine."
|
||||
return 1
|
||||
@@ -2934,7 +2934,7 @@ PY
|
||||
fi
|
||||
done
|
||||
|
||||
print_error "Vocalinux cannot start with this configuration and no working engine is available."
|
||||
print_error "Voculinux cannot start with this configuration and no working engine is available."
|
||||
print_error "Install the engine: $VENV_DIR/bin/pip install $(engine_pip_name "$CONFIGURED_ENGINE")"
|
||||
print_error "or edit $CONFIG_FILE and set speech_recognition.engine to an installed engine."
|
||||
return 1
|
||||
@@ -2954,7 +2954,7 @@ run_tests() {
|
||||
# Check if pytest is installed in the virtual environment
|
||||
if ! "$VENV_DIR/bin/python" -c "import pytest" &>/dev/null; then
|
||||
print_info "Installing pytest and related packages..."
|
||||
local PIP_LOG_FILE="$VOCALINUX_TMP_DIR/test-deps.log"
|
||||
local PIP_LOG_FILE="$VOCULINUX_TMP_DIR/test-deps.log"
|
||||
pip_install_extras_skip_pygobject "$PIP_LOG_FILE" dev || {
|
||||
print_error "Failed to install pytest. Cannot run tests."
|
||||
return 1
|
||||
@@ -2962,7 +2962,7 @@ run_tests() {
|
||||
fi
|
||||
|
||||
# Create a directory for test results
|
||||
local TEST_RESULTS_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/vocalinux/test_results"
|
||||
local TEST_RESULTS_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/voculinux/test_results"
|
||||
mkdir -p "$TEST_RESULTS_DIR"
|
||||
local TEST_RESULTS_FILE="$TEST_RESULTS_DIR/pytest_$(date +%Y%m%d_%H%M%S).xml"
|
||||
|
||||
@@ -3007,21 +3007,21 @@ verify_installation() {
|
||||
ISSUES=$((ISSUES + 1))
|
||||
fi
|
||||
|
||||
# Check if vocalinux command is available
|
||||
if ! command -v vocalinux &>/dev/null && [ ! -f "$VENV_DIR/bin/vocalinux" ]; then
|
||||
print_error "Vocalinux command not found."
|
||||
# Check if voculinux command is available
|
||||
if ! command -v voculinux &>/dev/null && [ ! -f "$VENV_DIR/bin/voculinux" ]; then
|
||||
print_error "Voculinux command not found."
|
||||
ISSUES=$((ISSUES + 1))
|
||||
fi
|
||||
|
||||
# Check if desktop entry is installed
|
||||
if [ ! -f "$DESKTOP_DIR/vocalinux.desktop" ]; then
|
||||
if [ ! -f "$DESKTOP_DIR/voculinux.desktop" ]; then
|
||||
print_warning "Desktop entry not found. Application may not appear in application menu."
|
||||
ISSUES=$((ISSUES + 1))
|
||||
fi
|
||||
|
||||
# Check if icons are installed
|
||||
local ICON_COUNT=0
|
||||
for icon in vocalinux.svg vocalinux-microphone.svg vocalinux-microphone-off.svg vocalinux-microphone-process.svg; do
|
||||
for icon in voculinux.svg voculinux-microphone.svg voculinux-microphone-off.svg voculinux-microphone-process.svg; do
|
||||
if [ -f "$ICON_DIR/$icon" ]; then
|
||||
ICON_COUNT=$((ICON_COUNT + 1))
|
||||
fi
|
||||
@@ -3034,7 +3034,7 @@ verify_installation() {
|
||||
|
||||
# Check if Python package is importable using venv python
|
||||
if ! "$VENV_DIR/bin/python" -c "import vocalinux" &>/dev/null; then
|
||||
print_error "Vocalinux Python package cannot be imported."
|
||||
print_error "Voculinux Python package cannot be imported."
|
||||
ISSUES=$((ISSUES + 1))
|
||||
fi
|
||||
|
||||
@@ -3094,7 +3094,7 @@ EOF
|
||||
|
||||
# Success or warning message
|
||||
if [ "$ISSUES" -eq 0 ]; then
|
||||
print_success "Vocalinux has been installed successfully!"
|
||||
print_success "Voculinux has been installed successfully!"
|
||||
else
|
||||
print_warning "Installation complete with $ISSUES minor issue(s)"
|
||||
print_warning "The application should still work normally."
|
||||
@@ -3141,12 +3141,12 @@ EOF
|
||||
echo " 📦 What Was Installed"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo " Application: Vocalinux (voice dictation for Linux)"
|
||||
echo " Application: Voculinux (voice dictation for Linux)"
|
||||
echo " Engine: $ENGINE_DISPLAY_NAME"
|
||||
if [[ -n "$BACKEND_INFO" ]]; then
|
||||
echo " Backend: $BACKEND_INFO"
|
||||
fi
|
||||
echo " Location: ${INSTALL_DIR:-\$HOME/.local/share/vocalinux}"
|
||||
echo " Location: ${INSTALL_DIR:-\$HOME/.local/share/voculinux}"
|
||||
echo " Virtual Env: $VENV_DIR"
|
||||
echo " Config: $CONFIG_DIR"
|
||||
echo ""
|
||||
@@ -3155,9 +3155,9 @@ EOF
|
||||
echo " 🚀 Getting Started"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "1. Launch Vocalinux"
|
||||
echo " • From app menu: Look for 'Vocalinux'"
|
||||
echo " • From terminal: Run 'vocalinux' command"
|
||||
echo "1. Launch Voculinux"
|
||||
echo " • From app menu: Look for 'Voculinux'"
|
||||
echo " • From terminal: Run 'voculinux' command"
|
||||
echo ""
|
||||
echo "2. Find the icon in your system tray (top bar)"
|
||||
echo " • Click for settings and status"
|
||||
@@ -3180,16 +3180,16 @@ EOF
|
||||
echo ""
|
||||
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo " 🔧 Managing Vocalinux"
|
||||
echo " 🔧 Managing Voculinux"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " vocalinux Start the application"
|
||||
echo " vocalinux --debug Start with debug logging"
|
||||
echo " vocalinux-gui Open settings GUI"
|
||||
echo " voculinux Start the application"
|
||||
echo " voculinux --debug Start with debug logging"
|
||||
echo " voculinux-gui Open settings GUI"
|
||||
echo ""
|
||||
echo "To activate the virtual environment:"
|
||||
echo " source ${ACTIVATION_SCRIPT:-activate-vocalinux.sh}"
|
||||
echo " source ${ACTIVATION_SCRIPT:-activate-voculinux.sh}"
|
||||
echo ""
|
||||
echo "To uninstall:"
|
||||
echo " ./uninstall.sh"
|
||||
@@ -3215,10 +3215,10 @@ EOF
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "Virtual environment: $VENV_DIR"
|
||||
echo "Desktop entry: $DESKTOP_DIR/vocalinux.desktop"
|
||||
echo "Desktop entry: $DESKTOP_DIR/voculinux.desktop"
|
||||
echo "Configuration: $CONFIG_DIR"
|
||||
echo "Data directory: $DATA_DIR"
|
||||
echo "Wrapper script: $HOME/.local/bin/vocalinux"
|
||||
echo "Wrapper script: $HOME/.local/bin/voculinux"
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Vocalinux justfile
|
||||
# Voculinux justfile
|
||||
# Convenient commands for development
|
||||
# Run `just` to list all recipes. Python tooling runs through `uv run` against
|
||||
# .venv/ — run `just deps` after cloning (requires uv).
|
||||
@@ -47,7 +47,7 @@ _check_build_deps:
|
||||
_tooling: _check_build_deps
|
||||
uv sync --inexact {{DEV_EXTRAS}}
|
||||
|
||||
# Install Vocalinux
|
||||
# Install Voculinux
|
||||
install:
|
||||
./install.sh
|
||||
|
||||
@@ -149,7 +149,7 @@ aur-gate:
|
||||
uv pip install --no-config --python "$WORK/venv/bin/python" \
|
||||
--require-hashes --no-deps --only-binary=:all: -r requirements/release-build.txt
|
||||
"$WORK/venv/bin/python" scripts/prepare_aur_source.py \
|
||||
--local-unattested --sdist "$WORK"/dist/vocalinux-*.tar.gz --output "$WORK/source"
|
||||
--local-unattested --sdist "$WORK"/dist/voculinux-*.tar.gz --output "$WORK/source"
|
||||
docker run --rm -v "$PWD:/repo:ro" -v "$WORK/source:/aur-source:ro" \
|
||||
-e AUR_SOURCE=/aur-source archlinux:latest bash /repo/packaging/aur/build-test.sh
|
||||
|
||||
@@ -294,11 +294,11 @@ clean:
|
||||
|
||||
# Run the installed application
|
||||
run:
|
||||
vocalinux
|
||||
voculinux
|
||||
|
||||
# Run the installed application with debug logging
|
||||
run-debug:
|
||||
vocalinux --debug
|
||||
voculinux --debug
|
||||
|
||||
# Run from source
|
||||
run-source: _tooling
|
||||
@@ -314,4 +314,4 @@ pre-commit: _tooling
|
||||
|
||||
# Print the current version
|
||||
version:
|
||||
@uv run --no-sync python -c "from src.vocalinux.version import __version__; print(__version__)"
|
||||
@uv run --no-sync python -c "from src.voculinux.version import __version__; print(__version__)"
|
||||
|
||||
@@ -130,7 +130,7 @@ if [ "$status" -ne 124 ] && [ "$status" -ne 0 ] && [ "$status" -ne 143 ]; then
|
||||
fail "the app exited with $status instead of running"
|
||||
fi
|
||||
|
||||
grep -q "Initializing Vocalinux" "$LOG" || {
|
||||
grep -q "Initializing Voculinux" "$LOG" || {
|
||||
tail -n 30 "$LOG" >&2
|
||||
fail "startup never reached component initialisation"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build a relocatable AppImage for Vocalinux, natively for whichever
|
||||
# Build a relocatable AppImage for Voculinux, natively for whichever
|
||||
# architecture this script runs on (x86_64 or aarch64) - no cross-compiling.
|
||||
#
|
||||
# Usage: build.sh <path-to-wheel> <version> [output-dir]
|
||||
@@ -26,10 +26,10 @@
|
||||
# pywhispercpp from source with GGML_VULKAN=1 when Vulkan headers and a
|
||||
# shader compiler are on the build host. The AppImage uses the host Vulkan
|
||||
# loader/ICDs at runtime (do not bundle NVIDIA/AMD driver ICDs).
|
||||
# Set VOCALINUX_APPIMAGE_REQUIRE_VULKAN=1 in CI so a failed rebuild fails
|
||||
# Set VOCULINUX_APPIMAGE_REQUIRE_VULKAN=1 in CI so a failed rebuild fails
|
||||
# the job instead of shipping a CPU-only image. Set
|
||||
# VOCALINUX_APPIMAGE_SKIP_VULKAN=1 to force the CPU wheel.
|
||||
# A build that produced libggml-vulkan.so is kept in VOCALINUX_APPIMAGE_CACHE
|
||||
# VOCULINUX_APPIMAGE_SKIP_VULKAN=1 to force the CPU wheel.
|
||||
# A build that produced libggml-vulkan.so is kept in VOCULINUX_APPIMAGE_CACHE
|
||||
# and reused while the base image, tool_checksums.txt, and the pywhispercpp
|
||||
# pin are unchanged. A CPU-only build is not cached.
|
||||
set -euo pipefail
|
||||
@@ -113,7 +113,7 @@ checkout_pinned() {
|
||||
git -C "$dest" checkout -q FETCH_HEAD
|
||||
}
|
||||
|
||||
# Seed typelibs Vocalinux imports directly, plus transitive GIR deps that Gtk
|
||||
# Seed typelibs Voculinux imports directly, plus transitive GIR deps that Gtk
|
||||
# and AppIndicator require (xlib, Dbusmenu, …). Without those, GI falls back to
|
||||
# the builder's baked-in path (/usr/lib/x86_64-linux-gnu/girepository-1.0), which
|
||||
# does not exist on Fedora/openSUSE/Arch — startup then reports "missing GTK3".
|
||||
@@ -241,7 +241,7 @@ uv_install() {
|
||||
"$UV" pip install --python "$PY_BIN" --prefix "$APPDIR/usr" "$@"
|
||||
}
|
||||
|
||||
echo "== Installing Vocalinux + runtime deps into the bundle =="
|
||||
echo "== Installing Voculinux + runtime deps into the bundle =="
|
||||
# From the lock, not from whatever PyPI serves today. vad.txt is a superset of
|
||||
# runtime.txt (a test keeps it that way, so this is one resolution rather than
|
||||
# two); appimage.txt adds the PyGObject the exports leave out. The wheel is last
|
||||
@@ -253,15 +253,15 @@ uv_install --require-hashes --no-deps -r "$REPO_ROOT/requirements/appimage.txt"
|
||||
uv_install --no-deps "$WHEEL"
|
||||
|
||||
echo "== Adding desktop entry + icon =="
|
||||
install -Dm644 "$REPO_ROOT/vocalinux.desktop" "$APPDIR/usr/share/applications/vocalinux.desktop"
|
||||
install -Dm644 "$REPO_ROOT/voculinux.desktop" "$APPDIR/usr/share/applications/voculinux.desktop"
|
||||
# AppImage desktop integration expects Exec=AppRun; set WM class for the tray app.
|
||||
sed -i \
|
||||
-e 's|^Exec=.*|Exec=AppRun|' \
|
||||
-e '/^StartupWMClass=/d' \
|
||||
"$APPDIR/usr/share/applications/vocalinux.desktop"
|
||||
printf 'StartupWMClass=vocalinux\n' >> "$APPDIR/usr/share/applications/vocalinux.desktop"
|
||||
install -Dm644 "$REPO_ROOT/resources/icons/scalable/vocalinux.svg" \
|
||||
"$APPDIR/usr/share/icons/hicolor/scalable/apps/vocalinux.svg"
|
||||
"$APPDIR/usr/share/applications/voculinux.desktop"
|
||||
printf 'StartupWMClass=voculinux\n' >> "$APPDIR/usr/share/applications/voculinux.desktop"
|
||||
install -Dm644 "$REPO_ROOT/resources/icons/scalable/voculinux.svg" \
|
||||
"$APPDIR/usr/share/icons/hicolor/scalable/apps/voculinux.svg"
|
||||
|
||||
copy_typelibs() {
|
||||
local dest="$1"
|
||||
@@ -363,7 +363,7 @@ ensure_build_tools() {
|
||||
|
||||
# ggml demands glslc (`find_package(Vulkan COMPONENTS glslc REQUIRED)`) and the
|
||||
# base image packages none, so build it from the pinned shaderc commit — ~4 min
|
||||
# on a runner, and CI caches it in VOCALINUX_APPIMAGE_CACHE since the commit is
|
||||
# on a runner, and CI caches it in VOCULINUX_APPIMAGE_CACHE since the commit is
|
||||
# its only input.
|
||||
ensure_glslc() {
|
||||
if command -v glslc >/dev/null 2>&1; then
|
||||
@@ -372,7 +372,7 @@ ensure_glslc() {
|
||||
fi
|
||||
local commit cache_dir src
|
||||
commit="$(pin_field shaderc 3)"
|
||||
cache_dir="${VOCALINUX_APPIMAGE_CACHE:-${XDG_CACHE_HOME:-$HOME/.cache}/vocalinux-appimage}/glslc-${commit}-${ARCH}"
|
||||
cache_dir="${VOCULINUX_APPIMAGE_CACHE:-${XDG_CACHE_HOME:-$HOME/.cache}/voculinux-appimage}/glslc-${commit}-${ARCH}"
|
||||
if [ ! -x "$cache_dir/glslc" ]; then
|
||||
echo "== Building glslc from shaderc ${commit:0:12} (this image packages none) =="
|
||||
ensure_build_tools
|
||||
@@ -486,7 +486,7 @@ _compile_pywhispercpp_vulkan() {
|
||||
if ! has_vulkan_build_deps; then
|
||||
echo "Vulkan build deps missing (libvulkan-dev plus a C++ compiler)." >&2
|
||||
if [ "$require_vulkan" = "1" ]; then
|
||||
echo "VOCALINUX_APPIMAGE_REQUIRE_VULKAN=1: refusing to ship a CPU-only AppImage." >&2
|
||||
echo "VOCULINUX_APPIMAGE_REQUIRE_VULKAN=1: refusing to ship a CPU-only AppImage." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Warning: AppImage will use a CPU-only baseline pywhispercpp build." >&2
|
||||
@@ -547,13 +547,13 @@ _compile_pywhispercpp_vulkan() {
|
||||
}
|
||||
|
||||
rebuild_pywhispercpp_vulkan() {
|
||||
local require_vulkan="${VOCALINUX_APPIMAGE_REQUIRE_VULKAN:-0}"
|
||||
if [ "${VOCALINUX_APPIMAGE_SKIP_VULKAN:-0}" = "1" ]; then
|
||||
echo "== Skipping pywhispercpp Vulkan rebuild (VOCALINUX_APPIMAGE_SKIP_VULKAN=1) =="
|
||||
local require_vulkan="${VOCULINUX_APPIMAGE_REQUIRE_VULKAN:-0}"
|
||||
if [ "${VOCULINUX_APPIMAGE_SKIP_VULKAN:-0}" = "1" ]; then
|
||||
echo "== Skipping pywhispercpp Vulkan rebuild (VOCULINUX_APPIMAGE_SKIP_VULKAN=1) =="
|
||||
return 0
|
||||
fi
|
||||
|
||||
# The Vocalinux wheel was installed above and is not part of this cache.
|
||||
# The Voculinux wheel was installed above and is not part of this cache.
|
||||
# A hit still replaces the CPU pywhispercpp wheel the lock just installed,
|
||||
# and it does not run _compile_pywhispercpp_vulkan.
|
||||
local cache_dir site
|
||||
@@ -593,8 +593,8 @@ export DEPLOY_GTK_VERSION=3
|
||||
"$TOOLDIR/linuxdeploy" --appdir "$APPDIR" \
|
||||
--plugin gtk \
|
||||
-e "$APPDIR/usr/bin/python3" \
|
||||
-d "$APPDIR/usr/share/applications/vocalinux.desktop" \
|
||||
-i "$APPDIR/usr/share/icons/hicolor/scalable/apps/vocalinux.svg"
|
||||
-d "$APPDIR/usr/share/applications/voculinux.desktop" \
|
||||
-i "$APPDIR/usr/share/icons/hicolor/scalable/apps/voculinux.svg"
|
||||
|
||||
# The plugin can change the bundle after PyGObject was installed. Check the
|
||||
# package and the version-agnostic Python path that AppRun and the GI smoke use
|
||||
@@ -689,14 +689,14 @@ GTK_HOOK="$APPDIR/apprun-hooks/linuxdeploy-plugin-gtk.sh"
|
||||
if [ -f "$GTK_HOOK" ]; then
|
||||
# Upstream forces GDK_BACKEND=x11 even on Wayland, which breaks hover/focus
|
||||
# for GTK widgets under Plasma (XWayland). Prefer native Wayland unless the
|
||||
# user opts into X11 via VOCALINUX_FORCE_X11=1.
|
||||
# user opts into X11 via VOCULINUX_FORCE_X11=1.
|
||||
"$APPDIR/usr/bin/python3" - "$GTK_HOOK" <<'PY'
|
||||
import pathlib, re, sys
|
||||
path = pathlib.Path(sys.argv[1])
|
||||
text = path.read_text()
|
||||
replacement = (
|
||||
'# Prefer Wayland when available; force X11 only when requested.\n'
|
||||
'if [ "${VOCALINUX_FORCE_X11:-0}" = "1" ]; then\n'
|
||||
'if [ "${VOCULINUX_FORCE_X11:-0}" = "1" ]; then\n'
|
||||
' export GDK_BACKEND=x11\n'
|
||||
'elif [ -n "${WAYLAND_DISPLAY:-}" ] || [ "${XDG_SESSION_TYPE:-}" = "wayland" ]; then\n'
|
||||
' export GDK_BACKEND=wayland\n'
|
||||
@@ -727,13 +727,13 @@ smoke_gi_imports() {
|
||||
local appdir="$1"
|
||||
unshare --user --mount --map-root-user bash -c "
|
||||
set -euo pipefail
|
||||
mkdir -p /tmp/vocalinux-empty-gi
|
||||
mkdir -p /tmp/voculinux-empty-gi
|
||||
for d in /usr/lib/x86_64-linux-gnu/girepository-1.0 \
|
||||
/usr/lib/aarch64-linux-gnu/girepository-1.0 \
|
||||
/usr/lib/girepository-1.0 \
|
||||
/usr/lib64/girepository-1.0; do
|
||||
if [ -d \"\$d\" ]; then
|
||||
mount --bind /tmp/vocalinux-empty-gi \"\$d\"
|
||||
mount --bind /tmp/voculinux-empty-gi \"\$d\"
|
||||
fi
|
||||
done
|
||||
export PYTHONHOME='$appdir/usr'
|
||||
@@ -797,6 +797,6 @@ else
|
||||
fi
|
||||
|
||||
echo "== Packaging AppImage =="
|
||||
OUTPUT="$OUTDIR/Vocalinux-${VERSION}-${ARCH}.AppImage"
|
||||
OUTPUT="$OUTDIR/Voculinux-${VERSION}-${ARCH}.AppImage"
|
||||
ARCH="$ARCH" "$TOOLDIR/appimagetool" "$APPDIR" "$OUTPUT"
|
||||
echo "Built $OUTPUT"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# tool_checksums.txt. This script is the part that runs inside that image; the
|
||||
# way in is docker-build.sh, which both CI and `just appimage` call:
|
||||
#
|
||||
# bash packaging/appimage/docker-build.sh dist/vocalinux-0.16.0-py3-none-any.whl 0.16.0 dist
|
||||
# bash packaging/appimage/docker-build.sh dist/voculinux-0.16.0-py3-none-any.whl 0.16.0 dist
|
||||
#
|
||||
# Only the interpreter and the Python packages are pinned by digest; these apt
|
||||
# packages are whatever the pinned image resolves to. That is the trade the base
|
||||
@@ -34,5 +34,5 @@ bash "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/build.sh" "$@"
|
||||
# results back to whoever started it (docker-build.sh passes its own ids).
|
||||
if [ -n "${HOST_UID:-}" ]; then
|
||||
chown -R "${HOST_UID}:${HOST_GID:-$HOST_UID}" "${3:-dist}" \
|
||||
"${VOCALINUX_APPIMAGE_CACHE:-/cache}" 2>/dev/null || true
|
||||
"${VOCULINUX_APPIMAGE_CACHE:-/cache}" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
# the AppImage links against, and building on the host instead means shipping
|
||||
# whatever that host happens to run.
|
||||
#
|
||||
# Honours VOCALINUX_APPIMAGE_REQUIRE_VULKAN / _SKIP_VULKAN like build.sh, and
|
||||
# keeps glslc and the pywhispercpp Vulkan build in VOCALINUX_APPIMAGE_CACHE
|
||||
# (~/.cache/vocalinux-appimage by default) so the next build reuses them.
|
||||
# Honours VOCULINUX_APPIMAGE_REQUIRE_VULKAN / _SKIP_VULKAN like build.sh, and
|
||||
# keeps glslc and the pywhispercpp Vulkan build in VOCULINUX_APPIMAGE_CACHE
|
||||
# (~/.cache/voculinux-appimage by default) so the next build reuses them.
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/../.." && pwd)"
|
||||
@@ -20,7 +20,7 @@ if [ -z "$IMAGE" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CACHE="${VOCALINUX_APPIMAGE_CACHE:-${XDG_CACHE_HOME:-$HOME/.cache}/vocalinux-appimage}"
|
||||
CACHE="${VOCULINUX_APPIMAGE_CACHE:-${XDG_CACHE_HOME:-$HOME/.cache}/voculinux-appimage}"
|
||||
mkdir -p "$CACHE"
|
||||
|
||||
# The wheel and output dir are given as host paths; the repo is mounted at the
|
||||
@@ -31,9 +31,9 @@ exec docker run --rm \
|
||||
--security-opt seccomp=unconfined \
|
||||
-v "$REPO_ROOT:$REPO_ROOT" -w "$REPO_ROOT" \
|
||||
-v "$CACHE:/cache" \
|
||||
-e VOCALINUX_APPIMAGE_CACHE=/cache \
|
||||
-e VOCALINUX_APPIMAGE_REQUIRE_VULKAN \
|
||||
-e VOCALINUX_APPIMAGE_SKIP_VULKAN \
|
||||
-e VOCULINUX_APPIMAGE_CACHE=/cache \
|
||||
-e VOCULINUX_APPIMAGE_REQUIRE_VULKAN \
|
||||
-e VOCULINUX_APPIMAGE_SKIP_VULKAN \
|
||||
-e CMAKE_BUILD_PARALLEL_LEVEL \
|
||||
-e HOST_UID="$(id -u)" \
|
||||
-e HOST_GID="$(id -g)" \
|
||||
|
||||
@@ -5,16 +5,16 @@
|
||||
# from it), every pin in tool_checksums.txt, the cmake/ninja pins in
|
||||
# requirements/appimage-tools.txt, the Vulkan flags in build.sh, and the
|
||||
# pywhispercpp sdist install.sh names. It does not depend on the rest of the
|
||||
# Vocalinux sources, so this id ignores the git commit and the Actions run id
|
||||
# Voculinux sources, so this id ignores the git commit and the Actions run id
|
||||
# on purpose: putting either in the cache key would rebuild on every push.
|
||||
set -euo pipefail
|
||||
|
||||
here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
repo="$(cd "$here/../.." && pwd)"
|
||||
pins="${VOCALINUX_PINS:-$repo/packaging/appimage/tool_checksums.txt}"
|
||||
install_sh="${VOCALINUX_INSTALL_SH:-$repo/install.sh}"
|
||||
tools="${VOCALINUX_APPIMAGE_TOOLS:-$repo/requirements/appimage-tools.txt}"
|
||||
build_sh="${VOCALINUX_BUILD_SH:-$repo/packaging/appimage/build.sh}"
|
||||
pins="${VOCULINUX_PINS:-$repo/packaging/appimage/tool_checksums.txt}"
|
||||
install_sh="${VOCULINUX_INSTALL_SH:-$repo/install.sh}"
|
||||
tools="${VOCULINUX_APPIMAGE_TOOLS:-$repo/requirements/appimage-tools.txt}"
|
||||
build_sh="${VOCULINUX_BUILD_SH:-$repo/packaging/appimage/build.sh}"
|
||||
|
||||
base="$(awk '$1=="base-image" {print $3; exit}' "$pins")"
|
||||
if [ -z "$base" ]; then
|
||||
|
||||
@@ -12,7 +12,7 @@ _NATIVE_CACHE_HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
pywhispercpp_native_cache_dir() {
|
||||
local arch="$1"
|
||||
local root id
|
||||
root="${VOCALINUX_APPIMAGE_CACHE:-${XDG_CACHE_HOME:-$HOME/.cache}/vocalinux-appimage}"
|
||||
root="${VOCULINUX_APPIMAGE_CACHE:-${XDG_CACHE_HOME:-$HOME/.cache}/voculinux-appimage}"
|
||||
id="$(bash "$_NATIVE_CACHE_HERE/native-cache-id.sh")"
|
||||
printf '%s\n' "$root/pywhispercpp-vulkan-${arch}-${id}"
|
||||
}
|
||||
@@ -26,7 +26,7 @@ pywhispercpp_cache_has_vulkan() {
|
||||
}
|
||||
|
||||
# Copy the pywhispercpp install out of a site-packages directory.
|
||||
# Leaves the rest of the prefix (Vocalinux, numpy, …) where it is.
|
||||
# Leaves the rest of the prefix (Voculinux, numpy, …) where it is.
|
||||
pywhispercpp_cache_publish() {
|
||||
local site="$1" dest="$2"
|
||||
local parent staging pattern backup
|
||||
|
||||
@@ -108,10 +108,10 @@ echo "== Satisfy the AUR-resolved depends for dependency resolution =="
|
||||
STUB="$WORKDIR/stub"
|
||||
mkdir -p "$STUB"
|
||||
cat >"$STUB/PKGBUILD" <<EOF
|
||||
pkgname=vocalinux-gate-stub
|
||||
pkgname=voculinux-gate-stub
|
||||
pkgver=1
|
||||
pkgrel=1
|
||||
pkgdesc="Satisfies the AUR-resolved depends of the vocalinux build gate"
|
||||
pkgdesc="Satisfies the AUR-resolved depends of the voculinux build gate"
|
||||
arch=('any')
|
||||
provides=('python-pywhispercpp' 'python-pynput')
|
||||
EOF
|
||||
@@ -169,12 +169,12 @@ pacman -U --noconfirm "$BUILD"/*.pkg.tar.* >/dev/null
|
||||
# The console script proves the wheel's entry points landed; the imports walk
|
||||
# every depends entry the package declares (gi/Gtk/AppIndicator, IBus, cairo,
|
||||
# pyaudio, numpy, requests, tqdm, psutil, evdev, xlib, pynput).
|
||||
vocalinux --version
|
||||
voculinux --version
|
||||
python - "$_version" <<'PY' || fail "the installed package does not import or has the wrong version"
|
||||
import sys
|
||||
from importlib.metadata import version
|
||||
|
||||
assert version("vocalinux") == sys.argv[1], "installed distribution version differs from the sdist"
|
||||
assert version("voculinux") == sys.argv[1], "installed distribution version differs from the sdist"
|
||||
|
||||
import vocalinux.main
|
||||
import vocalinux.ui.tray_indicator
|
||||
@@ -196,13 +196,13 @@ if [ "${AUR_SOURCE_ONLY:-0}" = 1 ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "== Build vocalinux-bin against a stub AppImage =="
|
||||
echo "== Build voculinux-bin against a stub AppImage =="
|
||||
# The -bin package's arch sources are the published release assets, which do
|
||||
# not exist for an untagged HEAD. A placeholder exercises the same package()
|
||||
# install path on this arch; the pinned sums still describe the real assets,
|
||||
# so this stage skips checksum verification — release.yml's updpkgsums keeps
|
||||
# the published PKGBUILD pinned to the actual files.
|
||||
BINPKGDIR="$REPO/packaging/aur/vocalinux-bin"
|
||||
BINPKGDIR="$REPO/packaging/aur/voculinux-bin"
|
||||
[ -f "$BINPKGDIR/PKGBUILD" ] || fail "$BINPKGDIR/PKGBUILD not found"
|
||||
# shellcheck source=/dev/null
|
||||
source "$BINPKGDIR/PKGBUILD"
|
||||
@@ -214,10 +214,10 @@ pacman_retry -S --needed --noconfirm --asdeps "${depends[@]}" >/dev/null
|
||||
# directory as that user — makepkg writes into it as `builder`.
|
||||
BINBUILD="$WORKDIR/binpkg"
|
||||
runuser -u builder -- mkdir -p "$BINBUILD"
|
||||
cp "$BINPKGDIR/PKGBUILD" "$BINPKGDIR/vocalinux.desktop" \
|
||||
"$BINPKGDIR/vocalinux.svg" "$BINPKGDIR/LICENSE" "$BINBUILD/"
|
||||
cp "$BINPKGDIR/PKGBUILD" "$BINPKGDIR/voculinux.desktop" \
|
||||
"$BINPKGDIR/voculinux.svg" "$BINPKGDIR/LICENSE" "$BINBUILD/"
|
||||
CARCH="$(uname -m)"
|
||||
printf 'aur gate stub\n' >"$BINBUILD/Vocalinux-${_tag}-${CARCH}.AppImage"
|
||||
printf 'aur gate stub\n' >"$BINBUILD/Voculinux-${_tag}-${CARCH}.AppImage"
|
||||
|
||||
(
|
||||
cd "$BINBUILD"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Maintainer: Jatin K Malik <jatinkrmalik@gmail.com>
|
||||
# Updated by .github/workflows/release.yml on v* tags. Setup: docs/AUR.md
|
||||
|
||||
pkgname=vocalinux-bin
|
||||
pkgname=voculinux-bin
|
||||
# AUR pkgver cannot contain hyphens (v0.14.0-beta -> 0.14.0beta).
|
||||
pkgver=0.17.0
|
||||
_tag=0.17.0
|
||||
@@ -28,17 +28,17 @@ optdepends=(
|
||||
'wl-clipboard: Wayland clipboard (wl-copy/wl-paste) injection fallbacks'
|
||||
'ydotool: uinput keystroke injection fallback'
|
||||
)
|
||||
provides=('vocalinux')
|
||||
conflicts=('vocalinux' 'vocalinux-git')
|
||||
provides=('voculinux')
|
||||
conflicts=('voculinux' 'voculinux-git')
|
||||
# Stripping would rewrite the runtime header of a self-mounting ELF.
|
||||
options=('!strip')
|
||||
source=(
|
||||
'vocalinux.desktop'
|
||||
'vocalinux.svg'
|
||||
'voculinux.desktop'
|
||||
'voculinux.svg'
|
||||
'LICENSE'
|
||||
)
|
||||
source_x86_64=("Vocalinux-${_tag}-x86_64.AppImage::https://github.com/VocaHQ/vocalinux/releases/download/v${_tag}/Vocalinux-${_tag}-x86_64.AppImage")
|
||||
source_aarch64=("Vocalinux-${_tag}-aarch64.AppImage::https://github.com/VocaHQ/vocalinux/releases/download/v${_tag}/Vocalinux-${_tag}-aarch64.AppImage")
|
||||
source_x86_64=("Voculinux-${_tag}-x86_64.AppImage::https://github.com/VocaHQ/vocalinux/releases/download/v${_tag}/Voculinux-${_tag}-x86_64.AppImage")
|
||||
source_aarch64=("Voculinux-${_tag}-aarch64.AppImage::https://github.com/VocaHQ/vocalinux/releases/download/v${_tag}/Voculinux-${_tag}-aarch64.AppImage")
|
||||
sha256sums=('837006a9c689146308eae8c57cba1cdcc06673a108e72f39231837c6f63ae487'
|
||||
'128b8939ffc00314a55d0600ab29c6a92dfb116138e088c59579a086616ec8ec'
|
||||
'8486a10c4393cee1c25392769ddd3b2d6c242d6ec7928e1414efff7dfb2f07ef')
|
||||
@@ -46,16 +46,16 @@ sha256sums_x86_64=('1a87408bf5bd8f9176c395a4da9ce28c68a1a7585bd67f125ff6037c4328
|
||||
sha256sums_aarch64=('b256fe8577e2733a4da3ae4f9c2b9717f10017ad8328b832070ce04edc996a7d')
|
||||
|
||||
package() {
|
||||
install -Dm755 "Vocalinux-${_tag}-${CARCH}.AppImage" \
|
||||
"${pkgdir}/opt/${pkgname}/Vocalinux-${_tag}-${CARCH}.AppImage"
|
||||
install -Dm755 "Voculinux-${_tag}-${CARCH}.AppImage" \
|
||||
"${pkgdir}/opt/${pkgname}/Voculinux-${_tag}-${CARCH}.AppImage"
|
||||
|
||||
install -Dm644 vocalinux.desktop \
|
||||
"${pkgdir}/usr/share/applications/vocalinux.desktop"
|
||||
install -Dm644 vocalinux.svg \
|
||||
"${pkgdir}/usr/share/icons/hicolor/scalable/apps/vocalinux.svg"
|
||||
install -Dm644 voculinux.desktop \
|
||||
"${pkgdir}/usr/share/applications/voculinux.desktop"
|
||||
install -Dm644 voculinux.svg \
|
||||
"${pkgdir}/usr/share/icons/hicolor/scalable/apps/voculinux.svg"
|
||||
install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
|
||||
|
||||
install -dm755 "${pkgdir}/usr/bin"
|
||||
ln -s "/opt/${pkgname}/Vocalinux-${_tag}-${CARCH}.AppImage" \
|
||||
"${pkgdir}/usr/bin/vocalinux"
|
||||
ln -s "/opt/${pkgname}/Voculinux-${_tag}-${CARCH}.AppImage" \
|
||||
"${pkgdir}/usr/bin/voculinux"
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Type=Application
|
||||
Name=Vocalinux
|
||||
Name=Voculinux
|
||||
Comment=Seamless voice dictation system for Linux
|
||||
GenericName=Voice Typing
|
||||
Exec=vocalinux
|
||||
Icon=vocalinux
|
||||
Exec=voculinux
|
||||
Icon=voculinux
|
||||
Terminal=false
|
||||
Categories=Utility;Accessibility;AudioVideo;
|
||||
Keywords=voice;typing;dictation;speech;recognition;transcription;accessibility;
|
||||
@@ -1,4 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 460 460" width="460" height="460" role="img" aria-label="Vocalinux">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 460 460" width="460" height="460" role="img" aria-label="Voculinux">
|
||||
<circle cx="229" cy="231.5" r="221.5" fill="#0F6B57"/>
|
||||
<path d="M 164 127 A 65 65 0 0 1 294 127 L 294 224 A 65 65 0 0 1 164 224 Z" fill="#F2F6F2"/>
|
||||
<path d="M 144.87 202.02 A 87 87 0 1 0 312.13 202.02" fill="none" stroke="#F2F6F2" stroke-width="18" stroke-linecap="round"/>
|
||||
|
Before Width: | Height: | Size: 887 B After Width: | Height: | Size: 887 B |
@@ -1,7 +1,7 @@
|
||||
# Maintainer: Jatin K Malik <jatinkrmalik@gmail.com>
|
||||
# Updated by .github/workflows/release.yml on v* tags. Setup: docs/AUR.md
|
||||
|
||||
pkgname=vocalinux
|
||||
pkgname=voculinux
|
||||
# AUR pkgver cannot contain hyphens (v0.14.0-beta -> 0.14.0beta).
|
||||
pkgver=0.18.4
|
||||
_tag=0.18.4
|
||||
@@ -58,7 +58,7 @@ optdepends=(
|
||||
'wtype: Wayland keystroke injection fallback'
|
||||
'gtk-layer-shell: dictation overlay as a layer surface on KDE and wlroots Wayland'
|
||||
)
|
||||
conflicts=('vocalinux-git')
|
||||
conflicts=('voculinux-git')
|
||||
source=("${pkgname}-${_version}.tar.gz::https://github.com/VocaHQ/vocalinux/releases/download/v${_tag}/${pkgname}-${_version}.tar.gz")
|
||||
# Canonical release sdist, also published on PyPI. prepare_aur_source.py verifies
|
||||
# its checksum/provenance before pinning the next version; publication never rehashes.
|
||||
@@ -74,7 +74,7 @@ package() {
|
||||
python -m installer --destdir="${pkgdir}" dist/*.whl
|
||||
|
||||
install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
|
||||
install -Dm644 vocalinux.desktop "${pkgdir}/usr/share/applications/vocalinux.desktop"
|
||||
install -Dm644 voculinux.desktop "${pkgdir}/usr/share/applications/voculinux.desktop"
|
||||
|
||||
for icon in resources/icons/scalable/*.svg; do
|
||||
install -Dm644 "$icon" "${pkgdir}/usr/share/icons/hicolor/scalable/apps/$(basename "$icon")"
|
||||
@@ -1,6 +1,6 @@
|
||||
# Vocalinux Flatpak Packaging
|
||||
# Voculinux Flatpak Packaging
|
||||
|
||||
Manifest and AppStream metadata for building Vocalinux as a Flatpak.
|
||||
Manifest and AppStream metadata for building Voculinux as a Flatpak.
|
||||
|
||||
## VocaHQ remote (auto-update)
|
||||
|
||||
@@ -9,33 +9,33 @@ Homebrew-tap analogue — which `release.yml` signs and publishes to
|
||||
`VocaHQ/vocalinux-flatpak` (GitHub Pages) on every stable `v*` tag:
|
||||
|
||||
```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 # each new release arrives here
|
||||
```
|
||||
|
||||
The `.flatpakref` adds the `vocahq` remote and resolves the GNOME runtime
|
||||
through Flathub via `RuntimeRepo=` — the manual equivalent is `remote-add`
|
||||
for `flathub` then `vocahq`, then `flatpak install vocahq
|
||||
com.vocalinux.Vocalinux`. Only the app is ours; `org.gnome.Platform//50`
|
||||
com.voculinux.Voculinux`. Only the app is ours; `org.gnome.Platform//50`
|
||||
still comes from Flathub. One-time repo/key setup:
|
||||
[docs/FLATPAK_REMOTE.md](../../docs/FLATPAK_REMOTE.md).
|
||||
|
||||
## GitHub Release bundles
|
||||
|
||||
Each `v*` GitHub Release attaches `Vocalinux-<version>-x86_64.flatpak` and
|
||||
`Vocalinux-<version>-aarch64.flatpak` as a no-remote fallback:
|
||||
Each `v*` GitHub Release attaches `Voculinux-<version>-x86_64.flatpak` and
|
||||
`Voculinux-<version>-aarch64.flatpak` as a no-remote fallback:
|
||||
|
||||
```bash
|
||||
# once: Flathub remote + GNOME runtime (the app itself is not on Flathub)
|
||||
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak install flathub org.gnome.Platform//50
|
||||
|
||||
flatpak install --user ./Vocalinux-<version>-x86_64.flatpak
|
||||
flatpak run com.vocalinux.Vocalinux
|
||||
flatpak install --user ./Voculinux-<version>-x86_64.flatpak
|
||||
flatpak run com.voculinux.Voculinux
|
||||
```
|
||||
|
||||
Bundles do **not** auto-update — the VocaHQ remote above is the path for
|
||||
that. Vocalinux is **not on Flathub** (submission
|
||||
that. Voculinux is **not on Flathub** (submission
|
||||
[flathub/flathub#9368](https://github.com/flathub/flathub/pull/9368) closed on
|
||||
policy grounds; we are not re-submitting). Local `flatpak-builder` remains for
|
||||
contributors (below).
|
||||
@@ -67,7 +67,7 @@ no narrower uinput flag).
|
||||
To disable device access while keeping GPU support for Vulkan whisper.cpp, run:
|
||||
|
||||
```bash
|
||||
flatpak override --user --nodevice=all --device=dri com.vocalinux.Vocalinux
|
||||
flatpak override --user --nodevice=all --device=dri com.voculinux.Voculinux
|
||||
```
|
||||
|
||||
On native X11, hotkeys still work through the X11 listener, except on GNOME X11,
|
||||
@@ -78,12 +78,12 @@ enable **Settings → Shortcuts → External Activation (Desktop Shortcut)** and
|
||||
bind a desktop shortcut to:
|
||||
|
||||
```bash
|
||||
gdbus call --session --dest com.vocalinux.Vocalinux --object-path /com/vocalinux/Vocalinux --method com.vocalinux.Vocalinux.Toggle
|
||||
gdbus call --session --dest com.voculinux.Voculinux --object-path /com/voculinux/Voculinux --method com.voculinux.Voculinux.Toggle
|
||||
```
|
||||
|
||||
Use toggle mode for this shortcut. A desktop shortcut only sends a key press,
|
||||
so it cannot support push-to-talk. Running
|
||||
`flatpak run com.vocalinux.Vocalinux --toggle` also works, but starts a sandbox
|
||||
`flatpak run com.voculinux.Voculinux --toggle` also works, but starts a sandbox
|
||||
on each press. The host `gdbus` command is immediate and does not start another
|
||||
sandbox.
|
||||
|
||||
@@ -100,19 +100,19 @@ flatpak install flathub org.gnome.Platform//50 org.gnome.Sdk//50
|
||||
# --user --install install for the current user
|
||||
# --repo=repo export a local repo (then bundle or lint)
|
||||
# --compose-url-policy=full --mirror-screenshots-url=https://dl.flathub.org/media
|
||||
flatpak-builder --force-clean build-dir packaging/flatpak/com.vocalinux.Vocalinux.yml
|
||||
flatpak-builder --force-clean build-dir packaging/flatpak/com.voculinux.Voculinux.yml
|
||||
|
||||
flatpak run com.vocalinux.Vocalinux --debug
|
||||
flatpak run com.voculinux.Voculinux --debug
|
||||
|
||||
# single-file bundle (after a --repo=repo build)
|
||||
flatpak build-bundle repo vocalinux.flatpak com.vocalinux.Vocalinux
|
||||
# elsewhere: flatpak install --user vocalinux.flatpak
|
||||
flatpak build-bundle repo voculinux.flatpak com.voculinux.Voculinux
|
||||
# elsewhere: flatpak install --user voculinux.flatpak
|
||||
```
|
||||
|
||||
Lint (needs `org.flatpak.Builder`):
|
||||
|
||||
```bash
|
||||
flatpak run --command=flatpak-builder-lint org.flatpak.Builder manifest packaging/flatpak/com.vocalinux.Vocalinux.yml
|
||||
flatpak run --command=flatpak-builder-lint org.flatpak.Builder manifest packaging/flatpak/com.voculinux.Voculinux.yml
|
||||
flatpak run --command=flatpak-builder-lint org.flatpak.Builder builddir build-dir
|
||||
flatpak run --command=flatpak-builder-lint org.flatpak.Builder repo repo # if you used --repo=repo
|
||||
```
|
||||
@@ -122,7 +122,7 @@ glycin loaders, `flatpak-builder --run` can fail to load themed SVG icons for an
|
||||
uninstalled stable app ID; it is still fine for non-GUI smokes:
|
||||
|
||||
```bash
|
||||
flatpak-builder --run build-dir packaging/flatpak/com.vocalinux.Vocalinux.yml \
|
||||
flatpak-builder --run build-dir packaging/flatpak/com.voculinux.Voculinux.yml \
|
||||
python3 -c 'from pywhispercpp.model import Model; print("pywhispercpp ok")'
|
||||
```
|
||||
|
||||
@@ -187,4 +187,4 @@ Release `.flatpak` assets are the supported paths.
|
||||
- IBus: `--talk-name=org.freedesktop.IBus`
|
||||
- Tray: `--talk-name=org.kde.StatusNotifierWatcher`
|
||||
|
||||
Config and models use Flatpak XDG dirs under `~/.var/app/com.vocalinux.Vocalinux/`.
|
||||
Config and models use Flatpak XDG dirs under `~/.var/app/com.voculinux.Voculinux/`.
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Type=Application
|
||||
Name=Vocalinux
|
||||
Name=Voculinux
|
||||
Comment=Free, offline voice dictation for Linux
|
||||
GenericName=Voice Typing
|
||||
Exec=vocalinux
|
||||
Icon=com.vocalinux.Vocalinux
|
||||
Exec=voculinux
|
||||
Icon=com.voculinux.Voculinux
|
||||
Terminal=false
|
||||
Categories=Utility;Accessibility;AudioVideo;
|
||||
Keywords=voice;typing;dictation;speech;recognition;transcription;accessibility;
|
||||
StartupNotify=true
|
||||
StartupWMClass=com.vocalinux.Vocalinux
|
||||
StartupWMClass=com.voculinux.Voculinux
|
||||
X-GNOME-UsesNotifications=true
|
||||
@@ -1,10 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop-application">
|
||||
<id>com.vocalinux.Vocalinux</id>
|
||||
<id>com.voculinux.Voculinux</id>
|
||||
|
||||
<name>Vocalinux</name>
|
||||
<name>Voculinux</name>
|
||||
<summary>Free, offline voice dictation for Linux</summary>
|
||||
<developer id="com.vocalinux">
|
||||
<developer id="com.voculinux">
|
||||
<name>Jatin K Malik</name>
|
||||
</developer>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
<description>
|
||||
<p>
|
||||
Vocalinux is a privacy-first, fully offline voice dictation system for Linux.
|
||||
Voculinux is a privacy-first, fully offline voice dictation system for Linux.
|
||||
Speak naturally and your words appear in any application — on X11 or Wayland —
|
||||
using local speech recognition. No cloud, no data leaves your machine.
|
||||
Speech recognition models are downloaded on first run.
|
||||
@@ -37,7 +37,7 @@
|
||||
</p>
|
||||
</description>
|
||||
|
||||
<launchable type="desktop-id">com.vocalinux.Vocalinux.desktop</launchable>
|
||||
<launchable type="desktop-id">com.voculinux.Voculinux.desktop</launchable>
|
||||
|
||||
<categories>
|
||||
<category>Utility</category>
|
||||
@@ -58,19 +58,19 @@
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<caption>Real-time voice-to-text transcription</caption>
|
||||
<image>https://vocalinux.com/screenshots/00-transcription.png</image>
|
||||
<image>https://voculinux.com/screenshots/00-transcription.png</image>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<caption>Speech engine settings</caption>
|
||||
<image>https://vocalinux.com/screenshots/settings-speech-engine.png</image>
|
||||
<image>https://voculinux.com/screenshots/settings-speech-engine.png</image>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<caption>System tray indicator</caption>
|
||||
<image>https://vocalinux.com/screenshots/02-system-tray.png</image>
|
||||
<image>https://voculinux.com/screenshots/02-system-tray.png</image>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
|
||||
<url type="homepage">https://vocalinux.com</url>
|
||||
<url type="homepage">https://voculinux.com</url>
|
||||
<url type="bugtracker">https://github.com/VocaHQ/vocalinux/issues</url>
|
||||
<url type="vcs-browser">https://github.com/VocaHQ/vocalinux</url>
|
||||
|
||||
@@ -172,7 +172,7 @@
|
||||
</release>
|
||||
<release version="0.14.0-beta" date="2026-07-14">
|
||||
<description>
|
||||
<p>Vocalinux 0.14.0-beta as Flatpak: whisper.cpp with Vulkan, XDG config/models/logs, XWayland text injection, and system tray integration.</p>
|
||||
<p>Voculinux 0.14.0-beta as Flatpak: whisper.cpp with Vulkan, XDG config/models/logs, XWayland text injection, and system tray integration.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.12.0-beta" date="2026-06-07">
|
||||
@@ -1,9 +1,9 @@
|
||||
app-id: com.vocalinux.Vocalinux
|
||||
app-id: com.voculinux.Voculinux
|
||||
branch: stable
|
||||
runtime: org.gnome.Platform
|
||||
runtime-version: "50"
|
||||
sdk: org.gnome.Sdk
|
||||
command: vocalinux
|
||||
command: voculinux
|
||||
|
||||
build-options:
|
||||
env:
|
||||
@@ -97,7 +97,7 @@ modules:
|
||||
|
||||
# uinput-based typing / paste chords for native Wayland clients.
|
||||
# Pinned to v1.0.4 (keycode:value key API). Distro 0.1.x uses "ctrl+v" instead;
|
||||
# vocalinux detects the installed CLI at runtime (see TextInjector).
|
||||
# voculinux detects the installed CLI at runtime (see TextInjector).
|
||||
- name: ydotool
|
||||
buildsystem: cmake-ninja
|
||||
config-opts:
|
||||
@@ -124,16 +124,16 @@ modules:
|
||||
- python3-build-dependencies.yaml
|
||||
- python3-dependencies.yaml
|
||||
|
||||
- name: vocalinux
|
||||
- name: voculinux
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- pip3 install --no-deps --no-build-isolation --prefix=/app .
|
||||
- install -Dm644 packaging/flatpak/com.vocalinux.Vocalinux.desktop -t /app/share/applications/
|
||||
- install -Dm644 resources/icons/scalable/vocalinux.svg /app/share/icons/hicolor/scalable/apps/com.vocalinux.Vocalinux.svg
|
||||
- install -Dm644 resources/icons/scalable/vocalinux-microphone-off.svg /app/share/icons/hicolor/scalable/apps/com.vocalinux.Vocalinux-microphone-off.svg
|
||||
- install -Dm644 resources/icons/scalable/vocalinux-microphone.svg /app/share/icons/hicolor/scalable/apps/com.vocalinux.Vocalinux-microphone.svg
|
||||
- install -Dm644 resources/icons/scalable/vocalinux-microphone-process.svg /app/share/icons/hicolor/scalable/apps/com.vocalinux.Vocalinux-microphone-process.svg
|
||||
- install -Dm644 packaging/flatpak/com.vocalinux.Vocalinux.metainfo.xml -t /app/share/metainfo/
|
||||
- install -Dm644 packaging/flatpak/com.voculinux.Voculinux.desktop -t /app/share/applications/
|
||||
- install -Dm644 resources/icons/scalable/voculinux.svg /app/share/icons/hicolor/scalable/apps/com.voculinux.Voculinux.svg
|
||||
- install -Dm644 resources/icons/scalable/voculinux-microphone-off.svg /app/share/icons/hicolor/scalable/apps/com.voculinux.Voculinux-microphone-off.svg
|
||||
- install -Dm644 resources/icons/scalable/voculinux-microphone.svg /app/share/icons/hicolor/scalable/apps/com.voculinux.Voculinux-microphone.svg
|
||||
- install -Dm644 resources/icons/scalable/voculinux-microphone-process.svg /app/share/icons/hicolor/scalable/apps/com.voculinux.Voculinux-microphone-process.svg
|
||||
- install -Dm644 packaging/flatpak/com.voculinux.Voculinux.metainfo.xml -t /app/share/metainfo/
|
||||
sources:
|
||||
- type: dir
|
||||
path: ../..
|
||||
@@ -27,7 +27,7 @@
|
||||
<h1>VocaHQ Flatpak remote</h1>
|
||||
<p>
|
||||
Self-hosted, signed OSTree repository for
|
||||
<a href="https://vocalinux.com">Vocalinux</a> — published on every stable
|
||||
<a href="https://voculinux.com">Voculinux</a> — published on every stable
|
||||
tagged release, so installs auto-update via <code>flatpak update</code>.
|
||||
</p>
|
||||
<pre><code>flatpak install __FLATPAKREF_URL__</code></pre>
|
||||
@@ -38,11 +38,11 @@
|
||||
</p>
|
||||
<pre><code>flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak remote-add --if-not-exists vocahq __FLATPAKREPO_URL__
|
||||
flatpak install vocahq com.vocalinux.Vocalinux</code></pre>
|
||||
flatpak install vocahq com.voculinux.Voculinux</code></pre>
|
||||
<p>
|
||||
The GNOME runtime still comes from Flathub — the
|
||||
<code>.flatpakref</code> declares <code>RuntimeRepo</code> so flatpak
|
||||
finds it there. Vocalinux itself is not on Flathub.
|
||||
finds it there. Voculinux itself is not on Flathub.
|
||||
</p>
|
||||
<p>
|
||||
<a href="https://github.com/VocaHQ/vocalinux">Source code</a> ·
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build vocalinux_<version>_<arch>.deb and vocalinux-<version>.<arch>.rpm.
|
||||
# Build voculinux_<version>_<arch>.deb and voculinux-<version>.<arch>.rpm.
|
||||
#
|
||||
# Usage: build.sh <path-to-vocalinux-wheel> <version> [output-dir]
|
||||
# Usage: build.sh <path-to-voculinux-wheel> <version> [output-dir]
|
||||
# version release version, e.g. 0.18.0 or 0.19.0-beta
|
||||
#
|
||||
# CI and releases run this inside docker-build.sh's pinned Debian 12 image;
|
||||
@@ -63,18 +63,18 @@ NFPM="$TOOLS/nfpm"
|
||||
PAYLOAD="$TOOLS/payload"
|
||||
DOC="$TOOLS/pkg-doc"
|
||||
install -d \
|
||||
"$PAYLOAD/usr/lib/vocalinux/app" \
|
||||
"$PAYLOAD/usr/lib/vocalinux/vendor" \
|
||||
"$PAYLOAD/usr/lib/voculinux/app" \
|
||||
"$PAYLOAD/usr/lib/voculinux/vendor" \
|
||||
"$PAYLOAD/usr/bin" \
|
||||
"$PAYLOAD/usr/share/applications" \
|
||||
"$PAYLOAD/usr/share/icons/hicolor/scalable/apps" \
|
||||
"$DOC"
|
||||
|
||||
# --- application payload ------------------------------------------------
|
||||
# The wheel is a zip; -m zipfile lays out vocalinux/ and its dist-info
|
||||
# The wheel is a zip; -m zipfile lays out voculinux/ and its dist-info
|
||||
# exactly where pip --target would, without pip's EXTERNALLY-MANAGED refusal
|
||||
# on Debian 12.
|
||||
python3 -m zipfile -e "$WHEEL" "$PAYLOAD/usr/lib/vocalinux/app/"
|
||||
python3 -m zipfile -e "$WHEEL" "$PAYLOAD/usr/lib/voculinux/app/"
|
||||
|
||||
# --- vendored wheels -----------------------------------------------------
|
||||
# Download each supported CPython's pywhispercpp wheel — it has no abi3 tag,
|
||||
@@ -99,7 +99,7 @@ for PYV in $VENDOR_PYS; do
|
||||
--python-version "$PYV" -r "$PINS_VENDOR" -d "$TOOLS/wheels/$PYV" >/dev/null
|
||||
done
|
||||
for VENDOR_WHEEL in "$TOOLS"/wheels/*/*.whl; do
|
||||
python3 -m zipfile -e "$VENDOR_WHEEL" "$PAYLOAD/usr/lib/vocalinux/vendor/"
|
||||
python3 -m zipfile -e "$VENDOR_WHEEL" "$PAYLOAD/usr/lib/voculinux/vendor/"
|
||||
done
|
||||
|
||||
# --- portable libggml-cpu -------------------------------------------------
|
||||
@@ -144,7 +144,7 @@ swapped=0
|
||||
while IFS= read -r vendored; do
|
||||
cp "$BASELINE_CPU" "$vendored"
|
||||
swapped=$((swapped + 1))
|
||||
done < <(find "$PAYLOAD/usr/lib/vocalinux/vendor" -name 'libggml-cpu*.so*')
|
||||
done < <(find "$PAYLOAD/usr/lib/voculinux/vendor" -name 'libggml-cpu*.so*')
|
||||
[ "$swapped" -gt 0 ] || fail "found no vendored libggml-cpu to replace"
|
||||
# The baseline library's own NEEDED entries use the unmangled sonames
|
||||
# (libggml-base.so.0, libgomp.so.1), so alias the vendored copies — the same
|
||||
@@ -157,30 +157,30 @@ while IFS= read -r libs_dir; do
|
||||
vendored_gomp="$(find "$libs_dir" -name 'libgomp*.so*' | head -1)"
|
||||
[ -n "$vendored_gomp" ] || fail "no vendored libgomp in $libs_dir"
|
||||
cp "$vendored_gomp" "$libs_dir/libgomp.so.1"
|
||||
done < <(find "$PAYLOAD/usr/lib/vocalinux/vendor" -type d -name 'pywhispercpp.libs')
|
||||
done < <(find "$PAYLOAD/usr/lib/voculinux/vendor" -type d -name 'pywhispercpp.libs')
|
||||
|
||||
# --- launchers -----------------------------------------------------------
|
||||
# Same environment install.sh's wrapper establishes: the vendored
|
||||
# pywhispercpp.libs on LD_LIBRARY_PATH, user site-packages off so they cannot
|
||||
# shadow the distro modules, and sg input so evdev hotkeys work on Wayland
|
||||
# when the user is already in the input group but the session has not picked
|
||||
# up the membership yet. vocalinux-gui exists because the wheel declares a
|
||||
# up the membership yet. voculinux-gui exists because the wheel declares a
|
||||
# gui-script of that name; on Linux it runs the same entry.
|
||||
write_launcher() {
|
||||
local path="$1"
|
||||
cat > "$path" <<'LAUNCHER_EOF'
|
||||
#!/bin/sh
|
||||
# Launcher for the distro-packaged Vocalinux. The vendored wheels (the
|
||||
# Launcher for the distro-packaged Voculinux. The vendored wheels (the
|
||||
# pywhispercpp/pynput copies Debian and Fedora do not ship) live under
|
||||
# /usr/lib/vocalinux/vendor with the app itself under .../app; the loader in
|
||||
# /usr/lib/voculinux/vendor with the app itself under .../app; the loader in
|
||||
# utils/pywhispercpp_loader.py finds the bundled .so files from sys.path.
|
||||
PYTHONNOUSERSITE=1
|
||||
VOCALINUX_VENDOR="/usr/lib/vocalinux/vendor"
|
||||
if [ -d "$VOCALINUX_VENDOR/pywhispercpp.libs" ]; then
|
||||
LD_LIBRARY_PATH="$VOCALINUX_VENDOR/pywhispercpp.libs${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
|
||||
VOCULINUX_VENDOR="/usr/lib/voculinux/vendor"
|
||||
if [ -d "$VOCULINUX_VENDOR/pywhispercpp.libs" ]; then
|
||||
LD_LIBRARY_PATH="$VOCULINUX_VENDOR/pywhispercpp.libs${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
|
||||
export LD_LIBRARY_PATH
|
||||
fi
|
||||
export PYTHONNOUSERSITE PYTHONPATH="/usr/lib/vocalinux/app:$VOCALINUX_VENDOR${PYTHONPATH:+:$PYTHONPATH}"
|
||||
export PYTHONNOUSERSITE PYTHONPATH="/usr/lib/voculinux/app:$VOCULINUX_VENDOR${PYTHONPATH:+:$PYTHONPATH}"
|
||||
if grep -q "^input:.*\b$(whoami)\b" /etc/group 2>/dev/null \
|
||||
&& ! groups | grep -q "\binput\b" && command -v sg >/dev/null 2>&1; then
|
||||
# sg(1) takes a single command string, so each argument is re-quoted for
|
||||
@@ -196,14 +196,14 @@ exec /usr/bin/python3 -m vocalinux.main "$@"
|
||||
LAUNCHER_EOF
|
||||
chmod 755 "$path"
|
||||
}
|
||||
write_launcher "$PAYLOAD/usr/bin/vocalinux"
|
||||
write_launcher "$PAYLOAD/usr/bin/vocalinux-gui"
|
||||
write_launcher "$PAYLOAD/usr/bin/voculinux"
|
||||
write_launcher "$PAYLOAD/usr/bin/voculinux-gui"
|
||||
|
||||
# --- desktop entry, icon, license ----------------------------------------
|
||||
install -Dm644 "$REPO_ROOT/vocalinux.desktop" \
|
||||
"$PAYLOAD/usr/share/applications/vocalinux.desktop"
|
||||
install -Dm644 "$REPO_ROOT/resources/icons/scalable/vocalinux.svg" \
|
||||
"$PAYLOAD/usr/share/icons/hicolor/scalable/apps/vocalinux.svg"
|
||||
install -Dm644 "$REPO_ROOT/voculinux.desktop" \
|
||||
"$PAYLOAD/usr/share/applications/voculinux.desktop"
|
||||
install -Dm644 "$REPO_ROOT/resources/icons/scalable/voculinux.svg" \
|
||||
"$PAYLOAD/usr/share/icons/hicolor/scalable/apps/voculinux.svg"
|
||||
install -Dm644 "$REPO_ROOT/LICENSE" "$DOC/LICENSE"
|
||||
|
||||
# --- package -------------------------------------------------------------
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
# the gi typelibs come from the distribution, and so do every Python
|
||||
# dependency the distros package. Only pywhispercpp and pynput are vendored —
|
||||
# pywhispercpp is not packaged by Debian or Fedora at all, and pynput is
|
||||
# missing from Fedora — both under /usr/lib/vocalinux/vendor/, on sys.path via
|
||||
# the launcher in /usr/bin/vocalinux. Vendoring the pywhispercpp wheel per
|
||||
# missing from Fedora — both under /usr/lib/voculinux/vendor/, on sys.path via
|
||||
# the launcher in /usr/bin/voculinux. Vendoring the pywhispercpp wheel per
|
||||
# supported CPython is what keeps the package free of a bundled interpreter.
|
||||
#
|
||||
# Version: VOCA_VERSION is the tag without its leading v and without a
|
||||
@@ -17,7 +17,7 @@
|
||||
# nfpm maps a prerelease to 0.19.0~beta-1, which orders before the stable
|
||||
# 0.19.0-1 in both formats.
|
||||
|
||||
name: vocalinux
|
||||
name: voculinux
|
||||
arch: ${VOCA_ARCH}
|
||||
platform: linux
|
||||
version: ${VOCA_VERSION}
|
||||
@@ -31,12 +31,12 @@ description: |
|
||||
transcribe speech locally (whisper.cpp by default), and type into the
|
||||
focused window. GTK, PyGObject and the interpreter come from the
|
||||
distribution; pywhispercpp and pynput are vendored under
|
||||
/usr/lib/vocalinux/vendor because neither distro packages them.
|
||||
/usr/lib/voculinux/vendor because neither distro packages them.
|
||||
homepage: https://github.com/VocaHQ/vocalinux
|
||||
license: AGPL-3.0-only
|
||||
|
||||
contents:
|
||||
# The staged payload tree: /usr/lib/vocalinux/{app,vendor}, the launchers in
|
||||
# The staged payload tree: /usr/lib/voculinux/{app,vendor}, the launchers in
|
||||
# /usr/bin, the desktop file and the hicolor icon. build.sh writes it.
|
||||
- src: ./payload/
|
||||
dst: /
|
||||
@@ -45,10 +45,10 @@ contents:
|
||||
# License placement differs between the formats: Debian policy wants the
|
||||
# copyright file under /usr/share/doc, Fedora marks /usr/share/licenses.
|
||||
- src: ./pkg-doc/LICENSE
|
||||
dst: /usr/share/doc/vocalinux/copyright
|
||||
dst: /usr/share/doc/voculinux/copyright
|
||||
packager: deb
|
||||
- src: ./pkg-doc/LICENSE
|
||||
dst: /usr/share/licenses/vocalinux/LICENSE
|
||||
dst: /usr/share/licenses/voculinux/LICENSE
|
||||
packager: rpm
|
||||
|
||||
overrides:
|
||||
|
||||
@@ -52,17 +52,17 @@ echo "== installed: $PKG"
|
||||
# before check_dependencies() touches GTK, so it proves the wrapper, the
|
||||
# PYTHONPATH layout and the entry module's import chain — the dependency
|
||||
# typelibs are exercised by the import smoke below.
|
||||
vocalinux --version
|
||||
vocalinux-gui --version
|
||||
voculinux --version
|
||||
voculinux-gui --version
|
||||
|
||||
# Import smoke in the shape of the AUR gate: the app modules, the vendored
|
||||
# pywhispercpp wheel, and the distro gi/GTK typelibs, all through the same
|
||||
# interpreter and environment the launcher sets up. pynput is only checked
|
||||
# for presence: its __init__ selects a display backend and raises ImportError
|
||||
# with no DISPLAY, which is why the app guards it with PYNPUT_AVAILABLE.
|
||||
PYTHONPATH="/usr/lib/vocalinux/app:/usr/lib/vocalinux/vendor" \
|
||||
PYTHONPATH="/usr/lib/voculinux/app:/usr/lib/voculinux/vendor" \
|
||||
PYTHONNOUSERSITE=1 \
|
||||
LD_LIBRARY_PATH="/usr/lib/vocalinux/vendor/pywhispercpp.libs" \
|
||||
LD_LIBRARY_PATH="/usr/lib/voculinux/vendor/pywhispercpp.libs" \
|
||||
/usr/bin/python3 - <<'PY'
|
||||
import importlib
|
||||
import importlib.util
|
||||
@@ -83,11 +83,11 @@ for module in MODULES:
|
||||
importlib.import_module(module)
|
||||
|
||||
spec = importlib.util.find_spec("pynput")
|
||||
assert spec and spec.origin and spec.origin.startswith("/usr/lib/vocalinux/vendor/"), \
|
||||
assert spec and spec.origin and spec.origin.startswith("/usr/lib/voculinux/vendor/"), \
|
||||
f"vendored pynput not found on sys.path: {spec}"
|
||||
|
||||
tag = f"cpython-{sys.version_info.major}{sys.version_info.minor}-"
|
||||
exts = [p.name for p in Path("/usr/lib/vocalinux/vendor").glob("_pywhispercpp.*.so")]
|
||||
exts = [p.name for p in Path("/usr/lib/voculinux/vendor").glob("_pywhispercpp.*.so")]
|
||||
assert any(tag in name for name in exts), \
|
||||
f"no _pywhispercpp extension for {tag[:-1]} among {exts}"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Vocalinux for Nix
|
||||
# Voculinux for Nix
|
||||
|
||||
A flake that builds Vocalinux against nixpkgs: GTK 3, PyGObject and the
|
||||
A flake that builds Voculinux against nixpkgs: GTK 3, PyGObject and the
|
||||
AppIndicator typelib come from nixpkgs, and `pywhispercpp` — which nixpkgs
|
||||
does not package — is built from its PyPI sdist (it vendors whisper.cpp and
|
||||
pybind11). Every host tool the app probes for (`xdotool`, `wtype`, `ydotool`,
|
||||
@@ -24,14 +24,14 @@ nix profile install github:VocaHQ/vocalinux
|
||||
|
||||
```nix
|
||||
{
|
||||
inputs.vocalinux.url = "github:VocaHQ/vocalinux";
|
||||
inputs.voculinux.url = "github:VocaHQ/vocalinux";
|
||||
|
||||
outputs = { nixpkgs, vocalinux, ... }: {
|
||||
outputs = { nixpkgs, voculinux, ... }: {
|
||||
nixosConfigurations.host = nixpkgs.lib.nixosSystem {
|
||||
modules = [
|
||||
vocalinux.nixosModules.vocalinux
|
||||
voculinux.nixosModules.voculinux
|
||||
{
|
||||
programs.vocalinux.enable = true;
|
||||
programs.voculinux.enable = true;
|
||||
users.users.you.extraGroups = [ "input" "uinput" ];
|
||||
}
|
||||
];
|
||||
@@ -53,14 +53,14 @@ and can skip the group lines entirely.
|
||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
inputs.home-manager.url = "github:nix-community/home-manager";
|
||||
inputs.home-manager.inputs.nixpkgs.follows = "nixpkgs";
|
||||
inputs.vocalinux.url = "github:VocaHQ/vocalinux";
|
||||
inputs.voculinux.url = "github:VocaHQ/vocalinux";
|
||||
|
||||
outputs = { nixpkgs, home-manager, vocalinux, ... }: {
|
||||
outputs = { nixpkgs, home-manager, voculinux, ... }: {
|
||||
homeConfigurations.you = home-manager.lib.homeManagerConfiguration {
|
||||
pkgs = nixpkgs.legacyPackages.x86_64-linux;
|
||||
modules = [
|
||||
vocalinux.homeManagerModules.vocalinux
|
||||
{ programs.vocalinux.enable = true; }
|
||||
voculinux.homeManagerModules.voculinux
|
||||
{ programs.voculinux.enable = true; }
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Home Manager module for Vocalinux.
|
||||
# Home Manager module for Voculinux.
|
||||
#
|
||||
# Installs the package into the user profile; device permissions are a
|
||||
# system concern, so pair it with the NixOS module (or the manual group
|
||||
@@ -6,16 +6,16 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.programs.vocalinux;
|
||||
cfg = config.programs.voculinux;
|
||||
in
|
||||
{
|
||||
options.programs.vocalinux = {
|
||||
enable = lib.mkEnableOption "Vocalinux voice dictation";
|
||||
options.programs.voculinux = {
|
||||
enable = lib.mkEnableOption "Voculinux voice dictation";
|
||||
|
||||
package = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
defaultText = "the package built by the vocalinux flake";
|
||||
description = "The vocalinux package to install.";
|
||||
defaultText = "the package built by the voculinux flake";
|
||||
description = "The voculinux package to install.";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# NixOS module for Vocalinux.
|
||||
# NixOS module for Voculinux.
|
||||
#
|
||||
# The flake wraps this file and injects the flake-built package as the
|
||||
# default (programs.vocalinux.package), so importing the module through
|
||||
# nixosModules.vocalinux needs no extra wiring. Imported on its own, set
|
||||
# programs.vocalinux.package to a vocalinux derivation.
|
||||
# default (programs.voculinux.package), so importing the module through
|
||||
# nixosModules.voculinux needs no extra wiring. Imported on its own, set
|
||||
# programs.voculinux.package to a voculinux derivation.
|
||||
#
|
||||
# What it cannot do for you: membership in the "input" group is per-user,
|
||||
# so the module documents it and each user opts in:
|
||||
@@ -16,16 +16,16 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.programs.vocalinux;
|
||||
cfg = config.programs.voculinux;
|
||||
in
|
||||
{
|
||||
options.programs.vocalinux = {
|
||||
enable = lib.mkEnableOption "Vocalinux voice dictation";
|
||||
options.programs.voculinux = {
|
||||
enable = lib.mkEnableOption "Voculinux voice dictation";
|
||||
|
||||
package = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
defaultText = "the package built by the vocalinux flake";
|
||||
description = "The vocalinux package to install.";
|
||||
defaultText = "the package built by the voculinux flake";
|
||||
description = "The voculinux package to install.";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Vocalinux for Nix.
|
||||
# Voculinux for Nix.
|
||||
#
|
||||
# Consumed by the repo flake (packages.<system>.vocalinux) and buildable with
|
||||
# Consumed by the repo flake (packages.<system>.voculinux) and buildable with
|
||||
# plain callPackage:
|
||||
#
|
||||
# pkgs.python3Packages.callPackage ./packaging/nix/package.nix {
|
||||
@@ -75,7 +75,7 @@ let
|
||||
];
|
||||
in
|
||||
buildPythonApplication {
|
||||
pname = "vocalinux";
|
||||
pname = "voculinux";
|
||||
|
||||
# Track src/vocalinux/version.py so release bumps need no edit here.
|
||||
# builtins.match is POSIX ERE (no \s class), so flatten newlines first.
|
||||
@@ -136,15 +136,15 @@ buildPythonApplication {
|
||||
'';
|
||||
|
||||
postInstall = ''
|
||||
install -Dm644 vocalinux.desktop \
|
||||
$out/share/applications/vocalinux.desktop
|
||||
install -Dm644 resources/icons/scalable/vocalinux.svg \
|
||||
$out/share/icons/hicolor/scalable/apps/vocalinux.svg
|
||||
install -Dm644 voculinux.desktop \
|
||||
$out/share/applications/voculinux.desktop
|
||||
install -Dm644 resources/icons/scalable/voculinux.svg \
|
||||
$out/share/icons/hicolor/scalable/apps/voculinux.svg
|
||||
'';
|
||||
|
||||
dontCheck = true; # test suite needs a session bus and X display
|
||||
|
||||
pythonImportsCheck = [ "vocalinux" ];
|
||||
pythonImportsCheck = [ "voculinux" ];
|
||||
|
||||
meta = {
|
||||
description = "Free, offline voice dictation for Linux";
|
||||
@@ -155,11 +155,11 @@ buildPythonApplication {
|
||||
|
||||
Wayland/evdev shortcuts and ydotool injection need device access: on
|
||||
NixOS enable hardware.uinput and add your user to the "input" and
|
||||
"uinput" groups; the programs.vocalinux NixOS module does the first part.
|
||||
"uinput" groups; the programs.voculinux NixOS module does the first part.
|
||||
'';
|
||||
homepage = "https://github.com/VocaHQ/vocalinux";
|
||||
license = lib.licenses.agpl3Only;
|
||||
mainProgram = "vocalinux";
|
||||
mainProgram = "voculinux";
|
||||
platforms = lib.platforms.linux;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ buildPythonPackage rec {
|
||||
env = {
|
||||
# The sdist ships no version.txt; setup.py falls back to this env var.
|
||||
PYWHISPERCPP_VERSION = version;
|
||||
# Build Vulkan as a shared backend: Vocalinux's GPU detector looks for
|
||||
# Build Vulkan as a shared backend: Voculinux's GPU detector looks for
|
||||
# libggml-vulkan.so. CMake's build-tree RPATH can leak /build into the
|
||||
# wheel; disable CMake RPATHs and let autoPatchelfHook set Nix runtime paths.
|
||||
CMAKE_ARGS = "-DBUILD_SHARED_LIBS=ON -DGGML_NATIVE=OFF -DGGML_VULKAN=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_SKIP_RPATH=ON";
|
||||
|
||||
@@ -5,7 +5,7 @@ requires = ["setuptools>=77"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "vocalinux"
|
||||
name = "voculinux"
|
||||
dynamic = ["version"]
|
||||
description = "A seamless voice dictation system for Linux"
|
||||
readme = "README.md"
|
||||
@@ -117,10 +117,10 @@ lint = [
|
||||
]
|
||||
|
||||
[project.scripts]
|
||||
vocalinux = "vocalinux.main:main"
|
||||
voculinux = "vocalinux.main:main"
|
||||
|
||||
[project.gui-scripts]
|
||||
vocalinux-gui = "vocalinux.main:main"
|
||||
voculinux-gui = "vocalinux.main:main"
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://github.com/VocaHQ/vocalinux"
|
||||
|
||||
@@ -360,7 +360,7 @@ evdev==1.9.3 ; sys_platform == 'linux' or 'linux' in sys_platform \
|
||||
--hash=sha256:2c140e01ac8437758fa23fe5c871397412461f42d421aa20241dc8fe8cfccbc9
|
||||
# via
|
||||
# pynput
|
||||
# vocalinux
|
||||
# voculinux
|
||||
filelock==4.2.1 \
|
||||
--hash=sha256:7be2662e9e826b9bba28afc0f843a123280d799a2ea44bb5d35ccec67905ae44 \
|
||||
--hash=sha256:c4c937ccac2a813cee448e662a56366cfb374c0f8702e75f295c412cc1c5d5a3
|
||||
@@ -547,7 +547,7 @@ mypy==2.3.1 \
|
||||
--hash=sha256:ef0c6335cda9d807f8193d8ff6204a72bc909fa9882aacbca14f43cdb7188306 \
|
||||
--hash=sha256:f5d716048611e85ca9eefb2e1baa5d73ede389b5820ded260ea27c757d667af8 \
|
||||
--hash=sha256:ff715e45b2231a8e85de1d163d1b42791e4d7aab8f5145f85fee1b710b735aff
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
mypy-extensions==1.1.0 \
|
||||
--hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \
|
||||
--hash=sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558
|
||||
@@ -633,7 +633,7 @@ numpy==2.4.6 ; python_full_version < '3.12' \
|
||||
--hash=sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20
|
||||
# via
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
# voculinux
|
||||
numpy==2.5.2 ; python_full_version >= '3.12' \
|
||||
--hash=sha256:0090ccdd57ec2703e9b49d0bf554767370581c1dd0a6b2bb2b2d9def317d042a \
|
||||
--hash=sha256:078f9b027b478c9379b9677babbf0f8b8f1ecfada27636d7b9a93990c638739f \
|
||||
@@ -703,7 +703,7 @@ numpy==2.5.2 ; python_full_version >= '3.12' \
|
||||
--hash=sha256:fd0d703772bba096843785bd38371e31bb4a0c1151497ad5739d182114a73f7f
|
||||
# via
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
# voculinux
|
||||
packaging==26.3 \
|
||||
--hash=sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79 \
|
||||
--hash=sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c
|
||||
@@ -733,7 +733,7 @@ pluggy==1.6.0 \
|
||||
pre-commit==4.6.2 \
|
||||
--hash=sha256:8f5d7bfb021ecdbcd9d49d89847082dd24172ccde534390081a679ad046e2441 \
|
||||
--hash=sha256:e2dde9a75d3bce11bd3831c26d134df00a2803c1d818be6a0383c3dcda25dc4e
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
psutil==7.2.2 \
|
||||
--hash=sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372 \
|
||||
--hash=sha256:076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9 \
|
||||
@@ -756,7 +756,7 @@ psutil==7.2.2 \
|
||||
--hash=sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486 \
|
||||
--hash=sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00 \
|
||||
--hash=sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
pyaudio==0.2.14 \
|
||||
--hash=sha256:12f2f1ba04e06ff95d80700a78967897a489c05e093e3bffa05a84ed9c0a7fa3 \
|
||||
--hash=sha256:506b32a595f8693811682ab4b127602d404df7dfc453b499c91a80d0f7bad289 \
|
||||
@@ -765,7 +765,7 @@ pyaudio==0.2.14 \
|
||||
--hash=sha256:78dfff3879b4994d1f4fc6485646a57755c6ee3c19647a491f790a0895bd2f87 \
|
||||
--hash=sha256:95328285b4dab57ea8c52a4a996cb52be6d629353315be5bfda403d15932a497 \
|
||||
--hash=sha256:bbeb01d36a2f472ae5ee5e1451cacc42112986abe622f735bb870a5db77cf903
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
pycairo==1.29.1 ; sys_platform == 'linux' \
|
||||
--hash=sha256:4fbd26b4af24c9787d84cf5448e34eb8dca064b732479aaecd03109520eebd5f
|
||||
# via pygobject
|
||||
@@ -784,7 +784,7 @@ pygments==2.21.0 \
|
||||
pynput==1.8.2 \
|
||||
--hash=sha256:8cc38cf13a6ab2749cb375678be8a0fd705d7ce49c8001ff5db4007a723bbef1 \
|
||||
--hash=sha256:f493c87157cd3861b4468f7f896857051762f44ed26f1b641e7cc5840a457087
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
pyobjc-core==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:122e6ad302a2abf5d4d4adb0156db751600ddf2768441696cba17b31323085e7 \
|
||||
--hash=sha256:2062e8ad30a310441cd022544a897553408bebeaa7820d5edba3c96fd7fd693b \
|
||||
@@ -853,7 +853,7 @@ pyobjc-framework-quartz==12.2.2 ; sys_platform == 'darwin' \
|
||||
pysocks==1.7.1 \
|
||||
--hash=sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5 \
|
||||
--hash=sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
pytest==9.1.1 \
|
||||
--hash=sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313 \
|
||||
--hash=sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c
|
||||
@@ -861,19 +861,19 @@ pytest==9.1.1 \
|
||||
# pytest-cov
|
||||
# pytest-mock
|
||||
# pytest-timeout
|
||||
# vocalinux
|
||||
# voculinux
|
||||
pytest-cov==7.1.0 \
|
||||
--hash=sha256:30674f2b5f6351aa09702a9c8c364f6a01c27aae0c1366ae8016160d1efc56b2 \
|
||||
--hash=sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
pytest-mock==3.15.1 \
|
||||
--hash=sha256:0a25e2eb88fe5168d535041d09a4529a188176ae608a6d249ee65abc0949630d \
|
||||
--hash=sha256:1849a238f6f396da19762269de72cb1814ab44416fa73a8686deac10b0d87a0f
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
pytest-timeout==2.4.0 \
|
||||
--hash=sha256:7e68e90b01f9eff71332b25001f85c75495fc4e3a836701876183c4bcfd0540a \
|
||||
--hash=sha256:c42667e5cdadb151aeb5b26d114aff6bdf5a907f176a007a30b940d3d865b5c2
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
python-discovery==1.6.4 \
|
||||
--hash=sha256:530179cc51a1816d512b15635b3dc931295ae12efb183783ad31190a5d425d2b \
|
||||
--hash=sha256:bc70d31f0ec5de11eda13d4d64c16e24b3506a65984684f2b6c98cb83b2ea9df
|
||||
@@ -948,7 +948,7 @@ pywhispercpp==1.5.0 \
|
||||
--hash=sha256:f5d13b4a7e34b9f4eebf70bff150ec36f4145c580bd5d812b9a3139611e7433c \
|
||||
--hash=sha256:f9b1cd9dd4c3eb7fb2b777529eb62618e58a6bb05be20f82b7b1afe3d0b12274 \
|
||||
--hash=sha256:fbdbb1bb236f4481ff6ea475aed9ed091393ddb02271df309645d71de207778d
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
pyyaml==6.0.3 \
|
||||
--hash=sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c \
|
||||
--hash=sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3 \
|
||||
@@ -1000,13 +1000,13 @@ pyyaml==6.0.3 \
|
||||
--hash=sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0
|
||||
# via
|
||||
# pre-commit
|
||||
# vocalinux
|
||||
# voculinux
|
||||
requests==2.34.2 \
|
||||
--hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \
|
||||
--hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed
|
||||
# via
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
# voculinux
|
||||
six==1.17.0 \
|
||||
--hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
|
||||
--hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81
|
||||
|
||||
@@ -215,10 +215,10 @@ evdev==1.9.3 ; sys_platform == 'linux' or 'linux' in sys_platform \
|
||||
--hash=sha256:2c140e01ac8437758fa23fe5c871397412461f42d421aa20241dc8fe8cfccbc9
|
||||
# via
|
||||
# pynput
|
||||
# vocalinux
|
||||
# voculinux
|
||||
faster-whisper==1.2.1 \
|
||||
--hash=sha256:79a66ad50688c0b794dd501dc340a736992a6342f7f95e5811be60b5224a26a7
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
filelock==4.2.1 \
|
||||
--hash=sha256:7be2662e9e826b9bba28afc0f843a123280d799a2ea44bb5d35ccec67905ae44 \
|
||||
--hash=sha256:c4c937ccac2a813cee448e662a56366cfb374c0f8702e75f295c412cc1c5d5a3
|
||||
@@ -351,7 +351,7 @@ numpy==2.4.6 ; python_full_version < '3.12' \
|
||||
# ctranslate2
|
||||
# onnxruntime
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
# voculinux
|
||||
numpy==2.5.2 ; python_full_version >= '3.12' \
|
||||
--hash=sha256:0090ccdd57ec2703e9b49d0bf554767370581c1dd0a6b2bb2b2d9def317d042a \
|
||||
--hash=sha256:078f9b027b478c9379b9677babbf0f8b8f1ecfada27636d7b9a93990c638739f \
|
||||
@@ -423,7 +423,7 @@ numpy==2.5.2 ; python_full_version >= '3.12' \
|
||||
# ctranslate2
|
||||
# onnxruntime
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
# voculinux
|
||||
onnxruntime==1.29.0 \
|
||||
--hash=sha256:07c5907474dec4a2792fd7626b753dc66707808385a6d9eecf993db0066a9d0f \
|
||||
--hash=sha256:0d4f427afac434b0070fe992b540ddf20a7aff2265f760f314d91331935b6b98 \
|
||||
@@ -492,7 +492,7 @@ psutil==7.2.2 \
|
||||
--hash=sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486 \
|
||||
--hash=sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00 \
|
||||
--hash=sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
pyaudio==0.2.14 \
|
||||
--hash=sha256:12f2f1ba04e06ff95d80700a78967897a489c05e093e3bffa05a84ed9c0a7fa3 \
|
||||
--hash=sha256:506b32a595f8693811682ab4b127602d404df7dfc453b499c91a80d0f7bad289 \
|
||||
@@ -501,14 +501,14 @@ pyaudio==0.2.14 \
|
||||
--hash=sha256:78dfff3879b4994d1f4fc6485646a57755c6ee3c19647a491f790a0895bd2f87 \
|
||||
--hash=sha256:95328285b4dab57ea8c52a4a996cb52be6d629353315be5bfda403d15932a497 \
|
||||
--hash=sha256:bbeb01d36a2f472ae5ee5e1451cacc42112986abe622f735bb870a5db77cf903
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
pycairo==1.29.1 ; sys_platform == 'linux' \
|
||||
--hash=sha256:4fbd26b4af24c9787d84cf5448e34eb8dca064b732479aaecd03109520eebd5f
|
||||
# via pygobject
|
||||
pynput==1.8.2 \
|
||||
--hash=sha256:8cc38cf13a6ab2749cb375678be8a0fd705d7ce49c8001ff5db4007a723bbef1 \
|
||||
--hash=sha256:f493c87157cd3861b4468f7f896857051762f44ed26f1b641e7cc5840a457087
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
pyobjc-core==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:122e6ad302a2abf5d4d4adb0156db751600ddf2768441696cba17b31323085e7 \
|
||||
--hash=sha256:2062e8ad30a310441cd022544a897553408bebeaa7820d5edba3c96fd7fd693b \
|
||||
@@ -577,7 +577,7 @@ pyobjc-framework-quartz==12.2.2 ; sys_platform == 'darwin' \
|
||||
pysocks==1.7.1 \
|
||||
--hash=sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5 \
|
||||
--hash=sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
python-xlib==0.33 ; 'linux' in sys_platform \
|
||||
--hash=sha256:55af7906a2c75ce6cb280a584776080602444f75815a7aff4d287bb2d7018b32 \
|
||||
--hash=sha256:c3534038d42e0df2f1392a1b30a15a4ff5fdc2b86cfa94f072bf11b10a164398
|
||||
@@ -619,7 +619,7 @@ pywhispercpp==1.5.0 \
|
||||
--hash=sha256:f5d13b4a7e34b9f4eebf70bff150ec36f4145c580bd5d812b9a3139611e7433c \
|
||||
--hash=sha256:f9b1cd9dd4c3eb7fb2b777529eb62618e58a6bb05be20f82b7b1afe3d0b12274 \
|
||||
--hash=sha256:fbdbb1bb236f4481ff6ea475aed9ed091393ddb02271df309645d71de207778d
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
pyyaml==6.0.3 \
|
||||
--hash=sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c \
|
||||
--hash=sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3 \
|
||||
@@ -677,7 +677,7 @@ requests==2.34.2 \
|
||||
--hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed
|
||||
# via
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
# voculinux
|
||||
six==1.17.0 \
|
||||
--hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
|
||||
--hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81
|
||||
|
||||
@@ -154,7 +154,7 @@ evdev==1.9.3 ; sys_platform == 'linux' or 'linux' in sys_platform \
|
||||
--hash=sha256:2c140e01ac8437758fa23fe5c871397412461f42d421aa20241dc8fe8cfccbc9
|
||||
# via
|
||||
# pynput
|
||||
# vocalinux
|
||||
# voculinux
|
||||
idna==3.19 \
|
||||
--hash=sha256:5e0811a4383b21dc5838069f801c4fb62113b7447663d2530d2bd6e77b49bf15 \
|
||||
--hash=sha256:815e7be7a7806d54abb586dc943addc79e8b2ee16915059658cbeff4b1b43bf4
|
||||
@@ -234,7 +234,7 @@ numpy==2.4.6 ; python_full_version < '3.12' \
|
||||
--hash=sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20
|
||||
# via
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
# voculinux
|
||||
numpy==2.5.2 ; python_full_version >= '3.12' \
|
||||
--hash=sha256:0090ccdd57ec2703e9b49d0bf554767370581c1dd0a6b2bb2b2d9def317d042a \
|
||||
--hash=sha256:078f9b027b478c9379b9677babbf0f8b8f1ecfada27636d7b9a93990c638739f \
|
||||
@@ -304,7 +304,7 @@ numpy==2.5.2 ; python_full_version >= '3.12' \
|
||||
--hash=sha256:fd0d703772bba096843785bd38371e31bb4a0c1151497ad5739d182114a73f7f
|
||||
# via
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
# voculinux
|
||||
platformdirs==4.11.3 \
|
||||
--hash=sha256:5ed065d443751de711da036041a7a214122efc4a4de393b3f4137ba5576540e7 \
|
||||
--hash=sha256:66a73d38a849810252df809a3d8bcbda8e26f6c189920e7535ad608a48dbb5ab
|
||||
@@ -331,7 +331,7 @@ psutil==7.2.2 \
|
||||
--hash=sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486 \
|
||||
--hash=sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00 \
|
||||
--hash=sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
pyaudio==0.2.14 \
|
||||
--hash=sha256:12f2f1ba04e06ff95d80700a78967897a489c05e093e3bffa05a84ed9c0a7fa3 \
|
||||
--hash=sha256:506b32a595f8693811682ab4b127602d404df7dfc453b499c91a80d0f7bad289 \
|
||||
@@ -340,14 +340,14 @@ pyaudio==0.2.14 \
|
||||
--hash=sha256:78dfff3879b4994d1f4fc6485646a57755c6ee3c19647a491f790a0895bd2f87 \
|
||||
--hash=sha256:95328285b4dab57ea8c52a4a996cb52be6d629353315be5bfda403d15932a497 \
|
||||
--hash=sha256:bbeb01d36a2f472ae5ee5e1451cacc42112986abe622f735bb870a5db77cf903
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
pycairo==1.29.1 ; sys_platform == 'linux' \
|
||||
--hash=sha256:4fbd26b4af24c9787d84cf5448e34eb8dca064b732479aaecd03109520eebd5f
|
||||
# via pygobject
|
||||
pynput==1.8.2 \
|
||||
--hash=sha256:8cc38cf13a6ab2749cb375678be8a0fd705d7ce49c8001ff5db4007a723bbef1 \
|
||||
--hash=sha256:f493c87157cd3861b4468f7f896857051762f44ed26f1b641e7cc5840a457087
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
pyobjc-core==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:122e6ad302a2abf5d4d4adb0156db751600ddf2768441696cba17b31323085e7 \
|
||||
--hash=sha256:2062e8ad30a310441cd022544a897553408bebeaa7820d5edba3c96fd7fd693b \
|
||||
@@ -416,7 +416,7 @@ pyobjc-framework-quartz==12.2.2 ; sys_platform == 'darwin' \
|
||||
pysocks==1.7.1 \
|
||||
--hash=sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5 \
|
||||
--hash=sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
python-xlib==0.33 ; 'linux' in sys_platform \
|
||||
--hash=sha256:55af7906a2c75ce6cb280a584776080602444f75815a7aff4d287bb2d7018b32 \
|
||||
--hash=sha256:c3534038d42e0df2f1392a1b30a15a4ff5fdc2b86cfa94f072bf11b10a164398
|
||||
@@ -458,13 +458,13 @@ pywhispercpp==1.5.0 \
|
||||
--hash=sha256:f5d13b4a7e34b9f4eebf70bff150ec36f4145c580bd5d812b9a3139611e7433c \
|
||||
--hash=sha256:f9b1cd9dd4c3eb7fb2b777529eb62618e58a6bb05be20f82b7b1afe3d0b12274 \
|
||||
--hash=sha256:fbdbb1bb236f4481ff6ea475aed9ed091393ddb02271df309645d71de207778d
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
requests==2.34.2 \
|
||||
--hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \
|
||||
--hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed
|
||||
# via
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
# voculinux
|
||||
sherpa-onnx==1.13.7 \
|
||||
--hash=sha256:01c4d001390f282bef653d229dce5d9da5009a804999449e33f890139f1f2da0 \
|
||||
--hash=sha256:026917d88fde36d5d86661e4a61c968dd741f43a96773ad742da13bffd030471 \
|
||||
@@ -507,7 +507,7 @@ sherpa-onnx==1.13.7 \
|
||||
--hash=sha256:ed40aee149f9e2e47d0b5cf1be21b2d662e5816bebdabdcdbbdb98b8a9928cbe \
|
||||
--hash=sha256:fce7cfab223d6bee0a58fa940b5057e2f3cf63613928b88e09ac99b477e40be0 \
|
||||
--hash=sha256:fed61cc23dba8f212eeb2723d2e90108d6de95734c5ae427aeafdb10f09ec184
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
sherpa-onnx-core==1.13.7 ; platform_machine != 'armv7l' \
|
||||
--hash=sha256:07de22f590299a68d9b5c985264f380579600a831ee95510ab12f4068800d08c \
|
||||
--hash=sha256:861c1e18fbf9bd2c725992c5a1797efe1b934b7df7bb18986d1fdc60e91290c9 \
|
||||
@@ -522,7 +522,7 @@ sherpa-onnx-core==1.13.7 ; platform_machine != 'armv7l' \
|
||||
--hash=sha256:e1e6333ecde50c69b8a43feff6eedf1033ec2a3fe58009506572bd717fc78e42 \
|
||||
--hash=sha256:e3066e94c24c898c5794e08507f955e14bc904299bac80f357d0bcb7d93e3825 \
|
||||
--hash=sha256:f48029e0c79b4cc654076806cbf62094a51dcd26c6bd1ce17db3bad03aff02b1
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
six==1.17.0 \
|
||||
--hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
|
||||
--hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81
|
||||
|
||||
@@ -154,7 +154,7 @@ evdev==1.9.3 ; sys_platform == 'linux' or 'linux' in sys_platform \
|
||||
--hash=sha256:2c140e01ac8437758fa23fe5c871397412461f42d421aa20241dc8fe8cfccbc9
|
||||
# via
|
||||
# pynput
|
||||
# vocalinux
|
||||
# voculinux
|
||||
idna==3.19 \
|
||||
--hash=sha256:5e0811a4383b21dc5838069f801c4fb62113b7447663d2530d2bd6e77b49bf15 \
|
||||
--hash=sha256:815e7be7a7806d54abb586dc943addc79e8b2ee16915059658cbeff4b1b43bf4
|
||||
@@ -234,7 +234,7 @@ numpy==2.4.6 ; python_full_version < '3.12' \
|
||||
--hash=sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20
|
||||
# via
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
# voculinux
|
||||
numpy==2.5.2 ; python_full_version >= '3.12' \
|
||||
--hash=sha256:0090ccdd57ec2703e9b49d0bf554767370581c1dd0a6b2bb2b2d9def317d042a \
|
||||
--hash=sha256:078f9b027b478c9379b9677babbf0f8b8f1ecfada27636d7b9a93990c638739f \
|
||||
@@ -304,7 +304,7 @@ numpy==2.5.2 ; python_full_version >= '3.12' \
|
||||
--hash=sha256:fd0d703772bba096843785bd38371e31bb4a0c1151497ad5739d182114a73f7f
|
||||
# via
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
# voculinux
|
||||
platformdirs==4.11.3 \
|
||||
--hash=sha256:5ed065d443751de711da036041a7a214122efc4a4de393b3f4137ba5576540e7 \
|
||||
--hash=sha256:66a73d38a849810252df809a3d8bcbda8e26f6c189920e7535ad608a48dbb5ab
|
||||
@@ -331,7 +331,7 @@ psutil==7.2.2 \
|
||||
--hash=sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486 \
|
||||
--hash=sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00 \
|
||||
--hash=sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
pyaudio==0.2.14 \
|
||||
--hash=sha256:12f2f1ba04e06ff95d80700a78967897a489c05e093e3bffa05a84ed9c0a7fa3 \
|
||||
--hash=sha256:506b32a595f8693811682ab4b127602d404df7dfc453b499c91a80d0f7bad289 \
|
||||
@@ -340,14 +340,14 @@ pyaudio==0.2.14 \
|
||||
--hash=sha256:78dfff3879b4994d1f4fc6485646a57755c6ee3c19647a491f790a0895bd2f87 \
|
||||
--hash=sha256:95328285b4dab57ea8c52a4a996cb52be6d629353315be5bfda403d15932a497 \
|
||||
--hash=sha256:bbeb01d36a2f472ae5ee5e1451cacc42112986abe622f735bb870a5db77cf903
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
pycairo==1.29.1 ; sys_platform == 'linux' \
|
||||
--hash=sha256:4fbd26b4af24c9787d84cf5448e34eb8dca064b732479aaecd03109520eebd5f
|
||||
# via pygobject
|
||||
pynput==1.8.2 \
|
||||
--hash=sha256:8cc38cf13a6ab2749cb375678be8a0fd705d7ce49c8001ff5db4007a723bbef1 \
|
||||
--hash=sha256:f493c87157cd3861b4468f7f896857051762f44ed26f1b641e7cc5840a457087
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
pyobjc-core==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:122e6ad302a2abf5d4d4adb0156db751600ddf2768441696cba17b31323085e7 \
|
||||
--hash=sha256:2062e8ad30a310441cd022544a897553408bebeaa7820d5edba3c96fd7fd693b \
|
||||
@@ -416,7 +416,7 @@ pyobjc-framework-quartz==12.2.2 ; sys_platform == 'darwin' \
|
||||
pysocks==1.7.1 \
|
||||
--hash=sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5 \
|
||||
--hash=sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
python-xlib==0.33 ; 'linux' in sys_platform \
|
||||
--hash=sha256:55af7906a2c75ce6cb280a584776080602444f75815a7aff4d287bb2d7018b32 \
|
||||
--hash=sha256:c3534038d42e0df2f1392a1b30a15a4ff5fdc2b86cfa94f072bf11b10a164398
|
||||
@@ -458,13 +458,13 @@ pywhispercpp==1.5.0 \
|
||||
--hash=sha256:f5d13b4a7e34b9f4eebf70bff150ec36f4145c580bd5d812b9a3139611e7433c \
|
||||
--hash=sha256:f9b1cd9dd4c3eb7fb2b777529eb62618e58a6bb05be20f82b7b1afe3d0b12274 \
|
||||
--hash=sha256:fbdbb1bb236f4481ff6ea475aed9ed091393ddb02271df309645d71de207778d
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
requests==2.34.2 \
|
||||
--hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \
|
||||
--hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed
|
||||
# via
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
# voculinux
|
||||
six==1.17.0 \
|
||||
--hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
|
||||
--hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81
|
||||
|
||||
@@ -154,7 +154,7 @@ evdev==1.9.3 ; sys_platform == 'linux' or 'linux' in sys_platform \
|
||||
--hash=sha256:2c140e01ac8437758fa23fe5c871397412461f42d421aa20241dc8fe8cfccbc9
|
||||
# via
|
||||
# pynput
|
||||
# vocalinux
|
||||
# voculinux
|
||||
flatbuffers==25.12.19 \
|
||||
--hash=sha256:7634f50c427838bb021c2d66a3d1168e9d199b0607e6329399f04846d42e20b4
|
||||
# via onnxruntime
|
||||
@@ -238,7 +238,7 @@ numpy==2.4.6 ; python_full_version < '3.12' \
|
||||
# via
|
||||
# onnxruntime
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
# voculinux
|
||||
numpy==2.5.2 ; python_full_version >= '3.12' \
|
||||
--hash=sha256:0090ccdd57ec2703e9b49d0bf554767370581c1dd0a6b2bb2b2d9def317d042a \
|
||||
--hash=sha256:078f9b027b478c9379b9677babbf0f8b8f1ecfada27636d7b9a93990c638739f \
|
||||
@@ -309,7 +309,7 @@ numpy==2.5.2 ; python_full_version >= '3.12' \
|
||||
# via
|
||||
# onnxruntime
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
# voculinux
|
||||
onnxruntime==1.29.0 \
|
||||
--hash=sha256:07c5907474dec4a2792fd7626b753dc66707808385a6d9eecf993db0066a9d0f \
|
||||
--hash=sha256:0d4f427afac434b0070fe992b540ddf20a7aff2265f760f314d91331935b6b98 \
|
||||
@@ -335,7 +335,7 @@ onnxruntime==1.29.0 \
|
||||
--hash=sha256:e2128f31f449e922c62dbe5d8b6b7b079f0bcaf2d56a102fa203cb6e5bb5ab19 \
|
||||
--hash=sha256:e417ef8628dcce310d2d53023e750ea298ec14d4341ae6dc3a572bfd9bc7fa97 \
|
||||
--hash=sha256:e74b278af1d949876f5d91d1268fd6c680e79f2bac194967394eaba9fdf69e7e
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
packaging==26.3 \
|
||||
--hash=sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79 \
|
||||
--hash=sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c
|
||||
@@ -376,7 +376,7 @@ psutil==7.2.2 \
|
||||
--hash=sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486 \
|
||||
--hash=sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00 \
|
||||
--hash=sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
pyaudio==0.2.14 \
|
||||
--hash=sha256:12f2f1ba04e06ff95d80700a78967897a489c05e093e3bffa05a84ed9c0a7fa3 \
|
||||
--hash=sha256:506b32a595f8693811682ab4b127602d404df7dfc453b499c91a80d0f7bad289 \
|
||||
@@ -385,14 +385,14 @@ pyaudio==0.2.14 \
|
||||
--hash=sha256:78dfff3879b4994d1f4fc6485646a57755c6ee3c19647a491f790a0895bd2f87 \
|
||||
--hash=sha256:95328285b4dab57ea8c52a4a996cb52be6d629353315be5bfda403d15932a497 \
|
||||
--hash=sha256:bbeb01d36a2f472ae5ee5e1451cacc42112986abe622f735bb870a5db77cf903
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
pycairo==1.29.1 ; sys_platform == 'linux' \
|
||||
--hash=sha256:4fbd26b4af24c9787d84cf5448e34eb8dca064b732479aaecd03109520eebd5f
|
||||
# via pygobject
|
||||
pynput==1.8.2 \
|
||||
--hash=sha256:8cc38cf13a6ab2749cb375678be8a0fd705d7ce49c8001ff5db4007a723bbef1 \
|
||||
--hash=sha256:f493c87157cd3861b4468f7f896857051762f44ed26f1b641e7cc5840a457087
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
pyobjc-core==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:122e6ad302a2abf5d4d4adb0156db751600ddf2768441696cba17b31323085e7 \
|
||||
--hash=sha256:2062e8ad30a310441cd022544a897553408bebeaa7820d5edba3c96fd7fd693b \
|
||||
@@ -461,7 +461,7 @@ pyobjc-framework-quartz==12.2.2 ; sys_platform == 'darwin' \
|
||||
pysocks==1.7.1 \
|
||||
--hash=sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5 \
|
||||
--hash=sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
python-xlib==0.33 ; 'linux' in sys_platform \
|
||||
--hash=sha256:55af7906a2c75ce6cb280a584776080602444f75815a7aff4d287bb2d7018b32 \
|
||||
--hash=sha256:c3534038d42e0df2f1392a1b30a15a4ff5fdc2b86cfa94f072bf11b10a164398
|
||||
@@ -503,13 +503,13 @@ pywhispercpp==1.5.0 \
|
||||
--hash=sha256:f5d13b4a7e34b9f4eebf70bff150ec36f4145c580bd5d812b9a3139611e7433c \
|
||||
--hash=sha256:f9b1cd9dd4c3eb7fb2b777529eb62618e58a6bb05be20f82b7b1afe3d0b12274 \
|
||||
--hash=sha256:fbdbb1bb236f4481ff6ea475aed9ed091393ddb02271df309645d71de207778d
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
requests==2.34.2 \
|
||||
--hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \
|
||||
--hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed
|
||||
# via
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
# voculinux
|
||||
six==1.17.0 \
|
||||
--hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
|
||||
--hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81
|
||||
|
||||
@@ -244,7 +244,7 @@ evdev==1.9.3 ; sys_platform == 'linux' or 'linux' in sys_platform \
|
||||
--hash=sha256:2c140e01ac8437758fa23fe5c871397412461f42d421aa20241dc8fe8cfccbc9
|
||||
# via
|
||||
# pynput
|
||||
# vocalinux
|
||||
# voculinux
|
||||
idna==3.19 \
|
||||
--hash=sha256:5e0811a4383b21dc5838069f801c4fb62113b7447663d2530d2bd6e77b49bf15 \
|
||||
--hash=sha256:815e7be7a7806d54abb586dc943addc79e8b2ee16915059658cbeff4b1b43bf4
|
||||
@@ -324,7 +324,7 @@ numpy==2.4.6 ; python_full_version < '3.12' \
|
||||
--hash=sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20
|
||||
# via
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
# voculinux
|
||||
numpy==2.5.2 ; python_full_version >= '3.12' \
|
||||
--hash=sha256:0090ccdd57ec2703e9b49d0bf554767370581c1dd0a6b2bb2b2d9def317d042a \
|
||||
--hash=sha256:078f9b027b478c9379b9677babbf0f8b8f1ecfada27636d7b9a93990c638739f \
|
||||
@@ -394,7 +394,7 @@ numpy==2.5.2 ; python_full_version >= '3.12' \
|
||||
--hash=sha256:fd0d703772bba096843785bd38371e31bb4a0c1151497ad5739d182114a73f7f
|
||||
# via
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
# voculinux
|
||||
platformdirs==4.11.3 \
|
||||
--hash=sha256:5ed065d443751de711da036041a7a214122efc4a4de393b3f4137ba5576540e7 \
|
||||
--hash=sha256:66a73d38a849810252df809a3d8bcbda8e26f6c189920e7535ad608a48dbb5ab
|
||||
@@ -421,7 +421,7 @@ psutil==7.2.2 \
|
||||
--hash=sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486 \
|
||||
--hash=sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00 \
|
||||
--hash=sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
pyaudio==0.2.14 \
|
||||
--hash=sha256:12f2f1ba04e06ff95d80700a78967897a489c05e093e3bffa05a84ed9c0a7fa3 \
|
||||
--hash=sha256:506b32a595f8693811682ab4b127602d404df7dfc453b499c91a80d0f7bad289 \
|
||||
@@ -430,7 +430,7 @@ pyaudio==0.2.14 \
|
||||
--hash=sha256:78dfff3879b4994d1f4fc6485646a57755c6ee3c19647a491f790a0895bd2f87 \
|
||||
--hash=sha256:95328285b4dab57ea8c52a4a996cb52be6d629353315be5bfda403d15932a497 \
|
||||
--hash=sha256:bbeb01d36a2f472ae5ee5e1451cacc42112986abe622f735bb870a5db77cf903
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
pycairo==1.29.1 ; sys_platform == 'linux' \
|
||||
--hash=sha256:4fbd26b4af24c9787d84cf5448e34eb8dca064b732479aaecd03109520eebd5f
|
||||
# via pygobject
|
||||
@@ -441,7 +441,7 @@ pycparser==3.0 ; implementation_name != 'PyPy' \
|
||||
pynput==1.8.2 \
|
||||
--hash=sha256:8cc38cf13a6ab2749cb375678be8a0fd705d7ce49c8001ff5db4007a723bbef1 \
|
||||
--hash=sha256:f493c87157cd3861b4468f7f896857051762f44ed26f1b641e7cc5840a457087
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
pyobjc-core==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:122e6ad302a2abf5d4d4adb0156db751600ddf2768441696cba17b31323085e7 \
|
||||
--hash=sha256:2062e8ad30a310441cd022544a897553408bebeaa7820d5edba3c96fd7fd693b \
|
||||
@@ -510,7 +510,7 @@ pyobjc-framework-quartz==12.2.2 ; sys_platform == 'darwin' \
|
||||
pysocks==1.7.1 \
|
||||
--hash=sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5 \
|
||||
--hash=sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
python-xlib==0.33 ; 'linux' in sys_platform \
|
||||
--hash=sha256:55af7906a2c75ce6cb280a584776080602444f75815a7aff4d287bb2d7018b32 \
|
||||
--hash=sha256:c3534038d42e0df2f1392a1b30a15a4ff5fdc2b86cfa94f072bf11b10a164398
|
||||
@@ -552,13 +552,13 @@ pywhispercpp==1.5.0 \
|
||||
--hash=sha256:f5d13b4a7e34b9f4eebf70bff150ec36f4145c580bd5d812b9a3139611e7433c \
|
||||
--hash=sha256:f9b1cd9dd4c3eb7fb2b777529eb62618e58a6bb05be20f82b7b1afe3d0b12274 \
|
||||
--hash=sha256:fbdbb1bb236f4481ff6ea475aed9ed091393ddb02271df309645d71de207778d
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
requests==2.34.2 \
|
||||
--hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \
|
||||
--hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed
|
||||
# via
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
# voculinux
|
||||
# vosk
|
||||
six==1.17.0 \
|
||||
--hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
|
||||
@@ -584,7 +584,7 @@ vosk==0.3.45 \
|
||||
--hash=sha256:4221f83287eefe5abbe54fc6f1da5774e9e3ffcbbdca1705a466b341093b072e \
|
||||
--hash=sha256:54efb47dd890e544e9e20f0316413acec7f8680d04ec095c6140ab4e70262704 \
|
||||
--hash=sha256:6994ddc68556c7e5730c3b6f6bad13320e3519b13ce3ed2aa25a86724e7c10ac
|
||||
# via vocalinux
|
||||
# via voculinux
|
||||
websockets==17.0.1 \
|
||||
--hash=sha256:02ed63bf26dda9fa27df730a41f6664586c4ee05972c8fb667ce1725b3fd13d3 \
|
||||
--hash=sha256:02f0b037a737d0cb0c33866c97bcd1a0b73170dfbf42d69d8fb86f51002fd5ae \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 1024 1024" role="img" aria-label="Vocalinux idle">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 1024 1024" role="img" aria-label="Voculinux idle">
|
||||
<!-- Opaque disc for StatusNotifier trays (~22px) -->
|
||||
<circle cx="512" cy="512" r="480" fill="#0B1A15"/>
|
||||
<g transform="translate(28.386 32.619) scale(2.116474)">
|
||||
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
@@ -1,4 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 1024 1024" role="img" aria-label="Vocalinux processing">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 1024 1024" role="img" aria-label="Voculinux processing">
|
||||
<!-- Opaque disc for StatusNotifier trays (~22px) -->
|
||||
<circle cx="512" cy="512" r="480" fill="#A86108"/>
|
||||
<g transform="translate(28.386 32.619) scale(2.116474)">
|
||||
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
@@ -1,4 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 1024 1024" role="img" aria-label="Vocalinux recording">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 1024 1024" role="img" aria-label="Voculinux recording">
|
||||
<!-- Opaque disc for StatusNotifier trays (~22px) -->
|
||||
<circle cx="512" cy="512" r="480" fill="#C73D38"/>
|
||||
<g transform="translate(28.386 32.619) scale(2.116474)">
|
||||
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
@@ -1,4 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 460 460" width="460" height="460" role="img" aria-label="Vocalinux">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 460 460" width="460" height="460" role="img" aria-label="Voculinux">
|
||||
<circle cx="229" cy="231.5" r="221.5" fill="#0F6B57"/>
|
||||
<path d="M 164 127 A 65 65 0 0 1 294 127 L 294 224 A 65 65 0 0 1 164 224 Z" fill="#F2F6F2"/>
|
||||
<path d="M 144.87 202.02 A 87 87 0 1 0 312.13 202.02" fill="none" stroke="#F2F6F2" stroke-width="18" stroke-linecap="round"/>
|
||||
|
Before Width: | Height: | Size: 887 B After Width: | Height: | Size: 887 B |
|
Before Width: | Height: | Size: 6.5 MiB After Width: | Height: | Size: 6.5 MiB |
@@ -232,7 +232,7 @@ def _build(python: str, output: Path, diagnostics: Path) -> None:
|
||||
env,
|
||||
diagnostics / "inputs.log",
|
||||
)
|
||||
with tempfile.TemporaryDirectory(prefix="vocalinux-wheel-") as temporary:
|
||||
with tempfile.TemporaryDirectory(prefix="voculinux-wheel-") as temporary:
|
||||
scratch = Path(temporary)
|
||||
source = scratch / "snapshot"
|
||||
source.mkdir()
|
||||
|
||||
@@ -6,7 +6,7 @@ check_deps() {
|
||||
MISSING=0
|
||||
WARNINGS=0
|
||||
|
||||
echo "Checking Vocalinux system dependencies..."
|
||||
echo "Checking Voculinux system dependencies..."
|
||||
echo ""
|
||||
|
||||
# Check for Python 3.11+ (requires-python in pyproject.toml)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Regenerate src/vocalinux/utils/model_checksums.txt from upstream metadata.
|
||||
|
||||
Vocalinux downloads 40MB-2GB speech models at install time and on first run,
|
||||
Voculinux downloads 40MB-2GB speech models at install time and on first run,
|
||||
then hands them to native code (whisper.cpp loads its ggml files through
|
||||
``ctypes.cdll``). Nothing about that is safe unless we know what we received,
|
||||
so every downloader checks the file against a hash pinned *in this repository*
|
||||
@@ -46,7 +46,7 @@ from typing import Iterable, NamedTuple
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
SRC = REPO_ROOT / "src"
|
||||
MANIFEST = SRC / "vocalinux" / "utils" / "model_checksums.txt"
|
||||
MANIFEST = SRC / "voculinux" / "utils" / "model_checksums.txt"
|
||||
|
||||
HF_REPO = "ggerganov/whisper.cpp"
|
||||
HF_API = f"https://huggingface.co/api/models/{HF_REPO}?blobs=true"
|
||||
@@ -65,7 +65,7 @@ class Entry(NamedTuple):
|
||||
|
||||
|
||||
def _fetch_json(url: str):
|
||||
request = urllib.request.Request(url, headers={"User-Agent": "vocalinux-checksum-generator"})
|
||||
request = urllib.request.Request(url, headers={"User-Agent": "voculinux-checksum-generator"})
|
||||
with urllib.request.urlopen(request, timeout=TIMEOUT) as response: # noqa: S310
|
||||
return json.load(response)
|
||||
|
||||
@@ -93,7 +93,7 @@ def _download_and_hash(url: str, expected_md5: str) -> tuple[str, int]:
|
||||
for rather than pinning either one.
|
||||
"""
|
||||
sha256, md5, size = hashlib.sha256(), hashlib.md5(), 0
|
||||
request = urllib.request.Request(url, headers={"User-Agent": "vocalinux-checksum-generator"})
|
||||
request = urllib.request.Request(url, headers={"User-Agent": "voculinux-checksum-generator"})
|
||||
with urllib.request.urlopen(request, timeout=TIMEOUT) as response: # noqa: S310
|
||||
for chunk in iter(lambda: response.read(1024 * 1024), b""):
|
||||
sha256.update(chunk)
|
||||
@@ -306,7 +306,7 @@ def _vosk_entries(wanted: Iterable[str], refresh: bool) -> list[Entry]:
|
||||
def _render(entries: list[Entry], revision: str) -> str:
|
||||
width = max(len(entry.filename) for entry in entries)
|
||||
lines = [
|
||||
"# Checksums for every speech model Vocalinux downloads.",
|
||||
"# Checksums for every speech model Voculinux downloads.",
|
||||
"#",
|
||||
"# Generated by scripts/generate-model-checksums.py -- do not edit by hand.",
|
||||
"# Regenerate with `just model-checksums` after adding a model to",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate Vocalinux notification WAVs.
|
||||
"""Generate Voculinux notification WAVs.
|
||||
|
||||
Writes 16-bit PCM mono files at 44.1 kHz into resources/sounds/:
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
# fetch+reset over the existing clone.
|
||||
#
|
||||
# The remote is a local mirror so the gate answers for *this commit*: the tag
|
||||
# is published from HEAD's tree and VOCALINUX_REPO_URL points the bootstrap at
|
||||
# is published from HEAD's tree and VOCULINUX_REPO_URL points the bootstrap at
|
||||
# it. A gate that cloned the public repo would install the last release, not
|
||||
# the checkout under test. The tag's own install.sh is the bootstrap: the #701
|
||||
# guardrail allows the bootstrap to come from main, and this commit's copy is
|
||||
@@ -37,10 +37,10 @@ INSTALL_HOME="/home/$INSTALL_USER"
|
||||
# Opaque on purpose: a name the public repository cannot already carry, so a
|
||||
# silent fallback to GitHub fails loudly instead of installing the wrong ref.
|
||||
GATE_TAG="${GATE_TAG:-v0.0.0-remote-gate}"
|
||||
MIRROR="/srv/vocalinux-remote.git"
|
||||
MIRROR="/srv/voculinux-remote.git"
|
||||
BOOTSTRAP="/tmp/vl.sh"
|
||||
CLONE_DIR="$INSTALL_HOME/.local/share/vocalinux-install"
|
||||
REMOTE_VENV="$INSTALL_HOME/.local/share/vocalinux/venv"
|
||||
CLONE_DIR="$INSTALL_HOME/.local/share/voculinux-install"
|
||||
REMOTE_VENV="$INSTALL_HOME/.local/share/voculinux/venv"
|
||||
|
||||
fail() {
|
||||
echo "FAIL: $*" >&2
|
||||
@@ -48,11 +48,11 @@ fail() {
|
||||
exit 1
|
||||
}
|
||||
|
||||
# install.sh writes a full transcript under ~/.local/state/vocalinux/. It is the
|
||||
# install.sh writes a full transcript under ~/.local/state/voculinux/. It is the
|
||||
# only place the per-distro package manager output survives.
|
||||
dump_install_log() {
|
||||
local log
|
||||
log="$(ls -1t "$INSTALL_HOME"/.local/state/vocalinux/install-*.log 2>/dev/null | head -n1 || true)"
|
||||
log="$(ls -1t "$INSTALL_HOME"/.local/state/voculinux/install-*.log 2>/dev/null | head -n1 || true)"
|
||||
if [ -n "$log" ]; then
|
||||
echo "== last 200 lines of $log ==" >&2
|
||||
tail -n 200 "$log" >&2
|
||||
@@ -142,9 +142,9 @@ chmod 0644 "$BOOTSTRAP"
|
||||
|
||||
run_remote_install() {
|
||||
# cd to $INSTALL_HOME so the bootstrap sees no checkout: local mode is chosen
|
||||
# by a pyproject.toml naming vocalinux in the working directory, and the
|
||||
# by a pyproject.toml naming voculinux in the working directory, and the
|
||||
# remote path is the one under test.
|
||||
su - "$INSTALL_USER" -c "cd '$INSTALL_HOME' && VOCALINUX_REPO_URL='file://$MIRROR' bash '$BOOTSTRAP' --auto --skip-models '--tag=$GATE_TAG'"
|
||||
su - "$INSTALL_USER" -c "cd '$INSTALL_HOME' && VOCULINUX_REPO_URL='file://$MIRROR' bash '$BOOTSTRAP' --auto --skip-models '--tag=$GATE_TAG'"
|
||||
}
|
||||
|
||||
# The user's literal `curl | bash`: installer code reaches bash on a pipe while
|
||||
@@ -187,7 +187,7 @@ drip "$bootstrap" | bash -s -- "$@"
|
||||
EOF
|
||||
chmod 0755 "$PIPED_FEED"
|
||||
run_remote_install_piped() {
|
||||
su - "$INSTALL_USER" -c "cd '$INSTALL_HOME' && VOCALINUX_REPO_URL='file://$MIRROR' script -qec \"'$PIPED_FEED' '$BOOTSTRAP' --auto --skip-models '--tag=$GATE_TAG'\" /dev/null"
|
||||
su - "$INSTALL_USER" -c "cd '$INSTALL_HOME' && VOCULINUX_REPO_URL='file://$MIRROR' script -qec \"'$PIPED_FEED' '$BOOTSTRAP' --auto --skip-models '--tag=$GATE_TAG'\" /dev/null"
|
||||
}
|
||||
|
||||
assert_remote_install() {
|
||||
@@ -223,20 +223,20 @@ assert_remote_install() {
|
||||
[ -x "$REMOTE_VENV/bin/python" ] \
|
||||
|| fail "no remote venv at $REMOTE_VENV; the handoff's --venv-dir did not reach the tagged installer"
|
||||
# The remote marker relocates the activation helper to ~/.local/bin only when
|
||||
# VOCALINUX_REMOTE_INSTALL survives the exec.
|
||||
[ -f "$INSTALL_HOME/.local/bin/activate-vocalinux.sh" ] \
|
||||
|| fail "no ~/.local/bin/activate-vocalinux.sh; the remote marker did not survive the handoff"
|
||||
# VOCULINUX_REMOTE_INSTALL survives the exec.
|
||||
[ -f "$INSTALL_HOME/.local/bin/activate-voculinux.sh" ] \
|
||||
|| fail "no ~/.local/bin/activate-voculinux.sh; the remote marker did not survive the handoff"
|
||||
# --skip-models forwarded: a model in the data dir means the tagged installer
|
||||
# re-parsed arguments the handoff did not deliver.
|
||||
if [ -d "$INSTALL_HOME/.local/share/vocalinux/models" ]; then
|
||||
[ -z "$(find "$INSTALL_HOME/.local/share/vocalinux/models" -type f -print -quit)" ] \
|
||||
if [ -d "$INSTALL_HOME/.local/share/voculinux/models" ]; then
|
||||
[ -z "$(find "$INSTALL_HOME/.local/share/voculinux/models" -type f -print -quit)" ] \
|
||||
|| fail "models were downloaded; --skip-models did not survive the handoff"
|
||||
fi
|
||||
|
||||
echo "== Assert: the installed app is there and answers =="
|
||||
[ -x "$INSTALL_HOME/.local/bin/vocalinux" ] || fail "no wrapper at ~/.local/bin/vocalinux"
|
||||
[ -x "$INSTALL_HOME/.local/bin/vocalinux-gui" ] || fail "no wrapper at ~/.local/bin/vocalinux-gui"
|
||||
[ -f "$INSTALL_HOME/.local/share/applications/vocalinux.desktop" ] \
|
||||
[ -x "$INSTALL_HOME/.local/bin/voculinux" ] || fail "no wrapper at ~/.local/bin/voculinux"
|
||||
[ -x "$INSTALL_HOME/.local/bin/voculinux-gui" ] || fail "no wrapper at ~/.local/bin/voculinux-gui"
|
||||
[ -f "$INSTALL_HOME/.local/share/applications/voculinux.desktop" ] \
|
||||
|| fail "no desktop entry; install_desktop_entry did not run"
|
||||
|
||||
# The version the wrapper reports must be the tag's own, not an assertion
|
||||
@@ -244,13 +244,13 @@ assert_remote_install() {
|
||||
local expected_version version_output
|
||||
expected_version="$(grep -oP '__version__\s*=\s*"\K[^"]+' "$CLONE_DIR/src/vocalinux/version.py")" \
|
||||
|| fail "cannot read __version__ from the clone's version.py"
|
||||
version_output="$(su - "$INSTALL_USER" -c "'$INSTALL_HOME/.local/bin/vocalinux' --version")" \
|
||||
version_output="$(su - "$INSTALL_USER" -c "'$INSTALL_HOME/.local/bin/voculinux' --version")" \
|
||||
|| fail "the installed wrapper cannot report a version"
|
||||
case "$version_output" in
|
||||
*"$expected_version"*) ;;
|
||||
*) fail "wrapper reports '$version_output', expected the tag's $expected_version" ;;
|
||||
esac
|
||||
echo " vocalinux --version: $version_output"
|
||||
echo " voculinux --version: $version_output"
|
||||
|
||||
# Same blind spots as the local gate: the injection binaries are reached
|
||||
# through subprocess, and the IBus runtime only where the package list
|
||||
@@ -320,7 +320,7 @@ su - "$INSTALL_USER" -c "git -C '$CLONE_DIR' reset --hard '$AWAY_SHA' \
|
||||
[ -z "$(git -C "$CLONE_DIR" tag -l "$GATE_TAG")" ] \
|
||||
|| fail "the clone kept refs/tags/$GATE_TAG; the re-run proves nothing"
|
||||
run_remote_install_piped || fail "the terminal-backed piped install exited non-zero over the existing clone"
|
||||
grep -l "Updating existing clone" "$INSTALL_HOME"/.local/state/vocalinux/install-*.log >/dev/null 2>&1 \
|
||||
grep -l "Updating existing clone" "$INSTALL_HOME"/.local/state/voculinux/install-*.log >/dev/null 2>&1 \
|
||||
|| fail "no install log shows 'Updating existing clone'; the fetch arm did not run"
|
||||
assert_remote_install
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
# exercise a path no user takes.
|
||||
#
|
||||
# Local mode only: install.sh chooses it by finding a pyproject.toml naming
|
||||
# vocalinux in the working directory, so extracting the tree and running from it
|
||||
# voculinux in the working directory, so extracting the tree and running from it
|
||||
# tests this commit. Remote mode (curl | bash, which clones the latest tag) is
|
||||
# not covered here.
|
||||
#
|
||||
@@ -33,7 +33,7 @@ INSTALL_HOME="/home/$INSTALL_USER"
|
||||
# Local mode puts the venv inside the tree, which is why the checkout is copied
|
||||
# rather than written to: a bind-mounted host tree would come back owned by a
|
||||
# container uid with a venv in it.
|
||||
TREE="$INSTALL_HOME/vocalinux"
|
||||
TREE="$INSTALL_HOME/voculinux"
|
||||
|
||||
fail() {
|
||||
echo "FAIL: $*" >&2
|
||||
@@ -41,11 +41,11 @@ fail() {
|
||||
exit 1
|
||||
}
|
||||
|
||||
# install.sh writes a full transcript under ~/.local/state/vocalinux/. It is the
|
||||
# install.sh writes a full transcript under ~/.local/state/voculinux/. It is the
|
||||
# only place the per-distro package manager output survives.
|
||||
dump_install_log() {
|
||||
local log
|
||||
log="$(ls -1t "$INSTALL_HOME"/.local/state/vocalinux/install-*.log 2>/dev/null | head -n1 || true)"
|
||||
log="$(ls -1t "$INSTALL_HOME"/.local/state/voculinux/install-*.log 2>/dev/null | head -n1 || true)"
|
||||
if [ -n "$log" ]; then
|
||||
echo "== last 200 lines of $log ==" >&2
|
||||
tail -n 200 "$log" >&2
|
||||
@@ -132,8 +132,8 @@ echo " install took $(( $(date +%s) - START ))s"
|
||||
echo "== Smoke: is there an installation, and does it import =="
|
||||
VENV="$TREE/venv"
|
||||
[ -x "$VENV/bin/python" ] || fail "no venv interpreter at $VENV/bin/python"
|
||||
[ -x "$INSTALL_HOME/.local/bin/vocalinux" ] || fail "no wrapper at ~/.local/bin/vocalinux"
|
||||
[ -f "$INSTALL_HOME/.local/share/applications/vocalinux.desktop" ] \
|
||||
[ -x "$INSTALL_HOME/.local/bin/voculinux" ] || fail "no wrapper at ~/.local/bin/voculinux"
|
||||
[ -f "$INSTALL_HOME/.local/share/applications/voculinux.desktop" ] \
|
||||
|| fail "no desktop entry; install_desktop_entry did not run"
|
||||
|
||||
# The injection backends are reached through subprocess, not GI, so no typelib
|
||||
@@ -159,7 +159,7 @@ esac
|
||||
# Through the wrapper rather than the venv directly: the wrapper is what the
|
||||
# desktop entry and the user's PATH invoke, and it carries the GI_TYPELIB_PATH
|
||||
# and pywhispercpp library-path resolution the bare console script does not.
|
||||
su - "$INSTALL_USER" -c "'$INSTALL_HOME/.local/bin/vocalinux' --version" \
|
||||
su - "$INSTALL_USER" -c "'$INSTALL_HOME/.local/bin/voculinux' --version" \
|
||||
|| fail "the installed wrapper cannot report a version"
|
||||
|
||||
su - "$INSTALL_USER" -c "'$VENV/bin/python' - " <<'PY' || fail "the installation does not import"
|
||||
|
||||
@@ -22,7 +22,7 @@ from pathlib import Path
|
||||
from packaging.version import Version
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
TEMPLATE = ROOT / "packaging/aur/vocalinux/PKGBUILD"
|
||||
TEMPLATE = ROOT / "packaging/aur/voculinux/PKGBUILD"
|
||||
REPOSITORY = "VocaHQ/vocalinux"
|
||||
|
||||
|
||||
@@ -33,14 +33,14 @@ def digest(path: Path) -> str:
|
||||
|
||||
|
||||
def sdist_version(sdist: Path) -> str:
|
||||
"""Require one canonical Vocalinux sdist with matching top-level metadata."""
|
||||
match = re.fullmatch(r"vocalinux-([0-9][A-Za-z0-9.+!]*)\.tar\.gz", sdist.name)
|
||||
"""Require one canonical Voculinux sdist with matching top-level metadata."""
|
||||
match = re.fullmatch(r"voculinux-([0-9][A-Za-z0-9.+!]*)\.tar\.gz", sdist.name)
|
||||
if not match:
|
||||
raise ValueError("expected a canonical vocalinux-VERSION.tar.gz sdist")
|
||||
raise ValueError("expected a canonical voculinux-VERSION.tar.gz sdist")
|
||||
version = match[1]
|
||||
if str(Version(version)) != version:
|
||||
raise ValueError("sdist filename version is not canonical")
|
||||
root = f"vocalinux-{version}"
|
||||
root = f"voculinux-{version}"
|
||||
with tarfile.open(sdist, "r:gz") as archive:
|
||||
members = archive.getmembers()
|
||||
if any(
|
||||
@@ -55,7 +55,7 @@ def sdist_version(sdist: Path) -> str:
|
||||
assert stream is not None
|
||||
with stream:
|
||||
info = BytesParser().parse(stream)
|
||||
if info.get_all("Name") != ["vocalinux"] or info.get_all("Version") != [version]:
|
||||
if info.get_all("Name") != ["voculinux"] or info.get_all("Version") != [version]:
|
||||
raise ValueError("sdist metadata does not match its filename")
|
||||
return version
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ from packaging.utils import canonicalize_name
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
EXPORT = REPO_ROOT / "requirements" / "vad.txt"
|
||||
DEPS_YAML = REPO_ROOT / "packaging" / "flatpak" / "python3-dependencies.yaml"
|
||||
MANIFEST = REPO_ROOT / "packaging" / "flatpak" / "com.vocalinux.Vocalinux.yml"
|
||||
MANIFEST = REPO_ROOT / "packaging" / "flatpak" / "com.voculinux.Voculinux.yml"
|
||||
|
||||
#: The environment the Flatpak build resolves for. GNOME 50 ships Python 3.13.
|
||||
#: numpy's lock entry splits at `python_full_version >= '3.12'`; onnxruntime's
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Vocalinux Remote API Test Server
|
||||
Voculinux Remote API Test Server
|
||||
|
||||
A simple mock server for testing Vocalinux's remote API feature.
|
||||
A simple mock server for testing Voculinux's remote API feature.
|
||||
Supports whisper.cpp (/inference) and OpenAI/FunASR-compatible
|
||||
(/v1/audio/transcriptions) formats.
|
||||
|
||||
@@ -22,7 +22,7 @@ from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||
|
||||
|
||||
class RemoteAPITestHandler(BaseHTTPRequestHandler):
|
||||
"""HTTP request handler for testing Vocalinux remote API."""
|
||||
"""HTTP request handler for testing Voculinux remote API."""
|
||||
|
||||
def log_message(self, format, *args):
|
||||
"""Custom log format with timestamp."""
|
||||
@@ -37,7 +37,7 @@ class RemoteAPITestHandler(BaseHTTPRequestHandler):
|
||||
self.end_headers()
|
||||
response = {
|
||||
"status": "ok",
|
||||
"message": "Vocalinux Remote API Test Server",
|
||||
"message": "Voculinux Remote API Test Server",
|
||||
"endpoints": [
|
||||
"/inference (whisper.cpp format)",
|
||||
"/v1/audio/transcriptions (OpenAI/FunASR format)",
|
||||
@@ -138,7 +138,7 @@ class RemoteAPITestHandler(BaseHTTPRequestHandler):
|
||||
if "test" in filename.lower():
|
||||
return "This is a test transcription from the mock server."
|
||||
elif "hello" in filename.lower():
|
||||
return "Hello, this is Vocalinux testing the remote API."
|
||||
return "Hello, this is Voculinux testing the remote API."
|
||||
elif "long" in filename.lower():
|
||||
return (
|
||||
"This is a longer transcription to test how the system handles "
|
||||
@@ -159,7 +159,7 @@ class DelayedHTTPServer(HTTPServer):
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Vocalinux Remote API Test Server"
|
||||
description="Voculinux Remote API Test Server"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--port",
|
||||
@@ -183,7 +183,7 @@ def main():
|
||||
args = parser.parse_args()
|
||||
|
||||
print("=" * 60)
|
||||
print("Vocalinux Remote API Test Server")
|
||||
print("Voculinux Remote API Test Server")
|
||||
print("=" * 60)
|
||||
print(f"Listening on: http://{args.host}:{args.port}")
|
||||
print(f"Processing delay: {args.delay}s")
|
||||
|
||||
@@ -26,7 +26,7 @@ import subprocess
|
||||
import sys
|
||||
|
||||
MANIFEST = "SHA256SUMS"
|
||||
PYPI_PROJECT = "vocalinux"
|
||||
PYPI_PROJECT = "voculinux"
|
||||
PYPI_SUFFIXES = (".whl", ".tar.gz")
|
||||
PYPI_TIMEOUT = 30
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Type=Application
|
||||
Name=Vocalinux
|
||||
Name=Voculinux
|
||||
Comment=Free, offline voice dictation for Linux
|
||||
GenericName=Voice Typing
|
||||
Exec=vocalinux
|
||||
Icon=${SNAP}/usr/share/icons/hicolor/scalable/apps/vocalinux.svg
|
||||
Exec=voculinux
|
||||
Icon=${SNAP}/usr/share/icons/hicolor/scalable/apps/voculinux.svg
|
||||
Terminal=false
|
||||
Categories=Utility;Accessibility;AudioVideo;
|
||||
Keywords=voice;typing;dictation;speech;recognition;transcription;accessibility;
|
||||
StartupNotify=true
|
||||
StartupWMClass=com.vocalinux.Vocalinux
|
||||
StartupWMClass=com.voculinux.Voculinux
|
||||
X-GNOME-UsesNotifications=true
|
||||
X-SnapInstanceName=vocalinux
|
||||
X-SnapInstanceName=voculinux
|
||||
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
@@ -54,7 +54,7 @@ def relocate_scripts(install: Path, tooling: Path) -> None:
|
||||
"if __name__ == '__main__':\n"
|
||||
" sys.exit(main())\n"
|
||||
)
|
||||
for name in ("vocalinux", "vocalinux-gui"):
|
||||
for name in ("voculinux", "voculinux-gui"):
|
||||
path = install / "bin" / name
|
||||
if path.is_symlink() or not path.is_file():
|
||||
raise RuntimeError(f"Missing installed entry point: {path}")
|
||||
|
||||
@@ -17,7 +17,7 @@ import runpy
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
MANIFEST = Path("usr/share/vocalinux/python-inputs.json")
|
||||
MANIFEST = Path("usr/share/voculinux/python-inputs.json")
|
||||
|
||||
|
||||
def normalize(name: str) -> str:
|
||||
@@ -80,7 +80,7 @@ def record(root: Path, source: Path) -> None:
|
||||
if importlib.metadata.version(name) != expected_version:
|
||||
raise RuntimeError(f"Build tool {name} differs from its locked version")
|
||||
expected = locked_versions(source / "requirements/runtime.txt")
|
||||
expected["vocalinux"] = runpy.run_path(str(source / "src/vocalinux/version.py"))["__version__"]
|
||||
expected["voculinux"] = runpy.run_path(str(source / "src/vocalinux/version.py"))["__version__"]
|
||||
audit(root, expected)
|
||||
manifest = {
|
||||
"python": list(sys.version_info[:2]),
|
||||
|
||||
@@ -7,16 +7,16 @@ if [ "$#" -ne 1 ] || [ ! -f "$1" ]; then
|
||||
echo "Usage: bash snap/local/smoke-test.sh PATH.snap" >&2
|
||||
exit 1
|
||||
fi
|
||||
if snap list vocalinux >/dev/null 2>&1; then
|
||||
echo "Refusing to replace an existing Vocalinux snap; use a disposable host" >&2
|
||||
if snap list voculinux >/dev/null 2>&1; then
|
||||
echo "Refusing to replace an existing Voculinux snap; use a disposable host" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sudo snap install --dangerous "$1"
|
||||
snap run vocalinux --version
|
||||
snap run voculinux --version
|
||||
# --shell does not run the application's command chain. Explicitly enter the
|
||||
# same GNOME desktop-launch environment before checking the installed payload.
|
||||
PYNPUT_BACKEND=dummy snap run --shell vocalinux -c '
|
||||
PYNPUT_BACKEND=dummy snap run --shell voculinux -c '
|
||||
exec "$SNAP/snap/command-chain/desktop-launch" "$SNAP/bin/python3" \
|
||||
"$SNAP/usr/lib/vocalinux/check_runtime.py" --root "$SNAP"
|
||||
"$SNAP/usr/lib/voculinux/check_runtime.py" --root "$SNAP"
|
||||
'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Vocalinux Snap packaging
|
||||
# Voculinux Snap packaging
|
||||
#
|
||||
# First ship: strict confinement, default whisper.cpp engine path, GTK tray UI,
|
||||
# mic capture, model download, and text injection (RemoteDesktop portal, wtype, xdotool).
|
||||
@@ -8,15 +8,15 @@
|
||||
# snapcraft pack
|
||||
# See docs/SNAP.md for controlled inputs, the build gate and verification limits.
|
||||
|
||||
name: vocalinux
|
||||
name: voculinux
|
||||
base: core24 # Ubuntu 24.04 / Python 3.12 (project requires-python >=3.11)
|
||||
# Fallback version; live version is set from src/vocalinux/version.py via
|
||||
# adopt-info + craftctl set in the vocalinux part (required for craftctl).
|
||||
# adopt-info + craftctl set in the voculinux part (required for craftctl).
|
||||
version: "0.17.0"
|
||||
adopt-info: vocalinux
|
||||
adopt-info: voculinux
|
||||
summary: Free offline voice dictation for Linux
|
||||
description: |
|
||||
Vocalinux is free voice typing for Linux. Hold a shortcut or toggle dictation, and text lands in almost any app on X11 or Wayland.
|
||||
Voculinux is free voice typing for Linux. Hold a shortcut or toggle dictation, and text lands in almost any app on X11 or Wayland.
|
||||
|
||||
Speech recognition runs on your machine after you download a model. No Voca account. No cloud transcription on the default path.
|
||||
|
||||
@@ -29,33 +29,33 @@ description: |
|
||||
- Text injection via the Wayland RemoteDesktop portal, wtype, or xdotool
|
||||
|
||||
Sandbox notes:
|
||||
- Global hotkeys need: sudo snap connect vocalinux:raw-input
|
||||
and sudo snap connect vocalinux:hardware-observe
|
||||
- Global hotkeys need: sudo snap connect voculinux:raw-input
|
||||
and sudo snap connect voculinux:hardware-observe
|
||||
- Native Wayland typing uses the RemoteDesktop portal: the compositor
|
||||
asks once on first dictation. The snap ships no uinput plug and no
|
||||
ydotool; the Store denied the super-privileged grant.
|
||||
- KDE Plasma: KWin's portal can mistype letter case (KDE bug 489021);
|
||||
set "Virtual Keyboard = IBus Wayland" so the IBus path delivers text.
|
||||
- Microphone may need: sudo snap connect vocalinux:audio-record
|
||||
- Microphone may need: sudo snap connect voculinux:audio-record
|
||||
The microphone list comes from the sound server, so pick a device
|
||||
in Settings rather than relying on the system default.
|
||||
- whisper.cpp runs on the CPU in this snap; it has no GPU backend.
|
||||
For Vulkan acceleration install the AppImage or use install.sh.
|
||||
- Config and models live under ~/snap/vocalinux/
|
||||
- Config and models live under ~/snap/voculinux/
|
||||
|
||||
grade: stable
|
||||
confinement: strict
|
||||
license: AGPL-3.0-only
|
||||
icon: snap/gui/vocalinux.png
|
||||
icon: snap/gui/voculinux.png
|
||||
contact: https://github.com/VocaHQ/vocalinux/issues
|
||||
issues: https://github.com/VocaHQ/vocalinux/issues
|
||||
website: https://vocalinux.com
|
||||
website: https://voculinux.com
|
||||
source-code: https://github.com/VocaHQ/vocalinux
|
||||
donation: https://github.com/sponsors/jatinkrmalik
|
||||
|
||||
apps:
|
||||
vocalinux:
|
||||
command: bin/vocalinux
|
||||
voculinux:
|
||||
command: bin/voculinux
|
||||
extensions: [gnome]
|
||||
plugs:
|
||||
# gnome extension already grants desktop, desktop-legacy, gsettings,
|
||||
@@ -67,17 +67,17 @@ apps:
|
||||
- network-bind # optional remote_api engine
|
||||
# Global hotkeys via python-evdev (/dev/input/event*).
|
||||
# Super-privileged: not auto-connected; user must:
|
||||
# sudo snap connect vocalinux:raw-input
|
||||
# sudo snap connect voculinux:raw-input
|
||||
- raw-input
|
||||
# Needed for /proc/bus/input/devices; not auto-connected:
|
||||
# sudo snap connect vocalinux:hardware-observe
|
||||
# sudo snap connect voculinux:hardware-observe
|
||||
- hardware-observe
|
||||
# No uinput plug; the RemoteDesktop portal types on Wayland instead.
|
||||
# The Store denied the super-privileged grant
|
||||
# (https://forum.snapcraft.io/t/53528), and ydotool is not staged
|
||||
# because it cannot reach /dev/uinput under confinement.
|
||||
common-id: com.vocalinux.Vocalinux
|
||||
desktop: usr/share/applications/vocalinux.desktop
|
||||
common-id: com.voculinux.Voculinux
|
||||
desktop: usr/share/applications/voculinux.desktop
|
||||
environment:
|
||||
# Prefer bundled CLI helpers (xdotool, xsel, xclip, wl-copy).
|
||||
# Do NOT prepend $SNAP/usr/lib over the gnome extension platform path:
|
||||
@@ -103,7 +103,7 @@ layout:
|
||||
bind: $SNAP/usr/lib/$CRAFT_ARCH_TRIPLET/alsa-lib
|
||||
|
||||
parts:
|
||||
vocalinux:
|
||||
voculinux:
|
||||
# The Python plugin would resolve dependencies and build tools again.
|
||||
plugin: nil
|
||||
source: .
|
||||
@@ -151,13 +151,13 @@ parts:
|
||||
--source "${CRAFT_PART_BUILD}" --install "${CRAFT_PART_INSTALL}" \
|
||||
--work "${CRAFT_PART_BUILD}/.snap-python-build"
|
||||
install -Dm644 "${CRAFT_PART_SRC}/snap/local/check_runtime.py" \
|
||||
"${CRAFT_PART_INSTALL}/usr/lib/vocalinux/check_runtime.py"
|
||||
install -Dm644 "${CRAFT_PROJECT_DIR}/snap/gui/vocalinux.desktop" \
|
||||
"${CRAFT_PART_INSTALL}/usr/share/applications/vocalinux.desktop"
|
||||
install -Dm644 "${CRAFT_PROJECT_DIR}/resources/icons/scalable/vocalinux.svg" \
|
||||
"${CRAFT_PART_INSTALL}/usr/share/icons/hicolor/scalable/apps/vocalinux.svg"
|
||||
"${CRAFT_PART_INSTALL}/usr/lib/voculinux/check_runtime.py"
|
||||
install -Dm644 "${CRAFT_PROJECT_DIR}/snap/gui/voculinux.desktop" \
|
||||
"${CRAFT_PART_INSTALL}/usr/share/applications/voculinux.desktop"
|
||||
install -Dm644 "${CRAFT_PROJECT_DIR}/resources/icons/scalable/voculinux.svg" \
|
||||
"${CRAFT_PART_INSTALL}/usr/share/icons/hicolor/scalable/apps/voculinux.svg"
|
||||
# meta/gui is what snapd uses for the store/desktop icon when present.
|
||||
install -Dm644 "${CRAFT_PROJECT_DIR}/resources/icons/scalable/vocalinux.svg" \
|
||||
install -Dm644 "${CRAFT_PROJECT_DIR}/resources/icons/scalable/voculinux.svg" \
|
||||
"${CRAFT_PART_INSTALL}/meta/gui/icon.svg"
|
||||
install -Dm644 "${CRAFT_PROJECT_DIR}/snap/local/alsa/asound.conf" \
|
||||
"${CRAFT_PART_INSTALL}/etc/asound.conf"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
Vocalinux - A seamless voice dictation system for Linux
|
||||
Voculinux - A seamless voice dictation system for Linux
|
||||
|
||||
Note: GTK-dependent modules are imported lazily in main.py to allow
|
||||
the package to be imported even when system GTK typelibs are not available.
|
||||
|
||||
@@ -1,68 +1,74 @@
|
||||
"""Central user-visible application identity for Vocalinux.
|
||||
"""Central user-visible application identity for Voculinux.
|
||||
|
||||
Ticket #17 prefactor: every user-visible identity string that is hardcoded in
|
||||
more than one place is driven from this single module. No value changes here;
|
||||
the rename ticket (#18) flips them in one place instead of a scavenger hunt.
|
||||
Ticket #18 rename: every user-visible identity string that is hardcoded in
|
||||
more than one place is driven from this single module. The fork takes its
|
||||
own name everywhere a user can see it; the internal ``voculinux`` Python
|
||||
package name is retained (see :data:`RETAINED_SURFACES`) and unrelated to
|
||||
these values.
|
||||
|
||||
Retained internal names (the ``vocalinux`` Python package, upstream URLs, and
|
||||
changelog history) are recorded in :data:`RETAINED_SURFACES`, not renamed.
|
||||
One-time legacy import of a previous Voculinux install lives in
|
||||
:mod:`vocalinux.legacy_import` and keys off :data:`LEGACY_APP_DIR_NAME`.
|
||||
"""
|
||||
|
||||
APP_NAME: str = "Vocalinux"
|
||||
APP_ID: str = "vocalinux"
|
||||
APP_DIR_NAME: str = "vocalinux"
|
||||
CLI_PROG: str = "vocalinux"
|
||||
APP_NAME: str = "Voculinux"
|
||||
APP_ID: str = "voculinux"
|
||||
APP_DIR_NAME: str = "voculinux"
|
||||
CLI_PROG: str = "voculinux"
|
||||
|
||||
BUS_NAME: str = "com.vocalinux.Vocalinux"
|
||||
OBJECT_PATH: str = "/com/vocalinux/Vocalinux"
|
||||
INTERFACE_NAME: str = "com.vocalinux.Vocalinux"
|
||||
BUS_NAME: str = "com.voculinux.Voculinux"
|
||||
OBJECT_PATH: str = "/com/voculinux/Voculinux"
|
||||
INTERFACE_NAME: str = "com.voculinux.Voculinux"
|
||||
|
||||
DESKTOP_FILENAME: str = "vocalinux.desktop"
|
||||
DESKTOP_ICON_NAME: str = "vocalinux"
|
||||
DESKTOP_FILENAME: str = "voculinux.desktop"
|
||||
DESKTOP_ICON_NAME: str = "voculinux"
|
||||
|
||||
TRAY_TITLE: str = APP_NAME
|
||||
ICON_DEFAULT: str = "vocalinux-microphone-off"
|
||||
ICON_ACTIVE: str = "vocalinux-microphone"
|
||||
ICON_PROCESSING: str = "vocalinux-microphone-process"
|
||||
ICON_DEFAULT: str = "voculinux-microphone-off"
|
||||
ICON_ACTIVE: str = "voculinux-microphone"
|
||||
ICON_PROCESSING: str = "voculinux-microphone-process"
|
||||
ICON_BASE_NAMES: tuple[str, ...] = (
|
||||
"vocalinux",
|
||||
"voculinux",
|
||||
ICON_ACTIVE,
|
||||
ICON_DEFAULT,
|
||||
ICON_PROCESSING,
|
||||
)
|
||||
|
||||
ENGINE_NAME: str = "vocalinux"
|
||||
ENGINE_LONGNAME: str = "Vocalinux"
|
||||
ENGINE_DESCRIPTION: str = "Vocalinux voice dictation (use as default input method)"
|
||||
COMPONENT_NAME: str = "org.freedesktop.IBus.Vocalinux"
|
||||
IBUS_DIR_NAME: str = "vocalinux-ibus"
|
||||
IBUS_TEXTDOMAIN: str = "vocalinux"
|
||||
ENGINE_NAME: str = "voculinux"
|
||||
ENGINE_LONGNAME: str = "Voculinux"
|
||||
ENGINE_DESCRIPTION: str = "Voculinux voice dictation (use as default input method)"
|
||||
COMPONENT_NAME: str = "org.freedesktop.IBus.Voculinux"
|
||||
IBUS_DIR_NAME: str = "voculinux-ibus"
|
||||
IBUS_TEXTDOMAIN: str = "voculinux"
|
||||
|
||||
UPDATE_CHECKER_USER_AGENT: str = "Vocalinux-UpdateChecker"
|
||||
UPDATE_CHECKER_USER_AGENT: str = "Voculinux-UpdateChecker"
|
||||
|
||||
RESOURCE_DIR_NAME: str = "vocalinux"
|
||||
RESOURCE_DIR_NAME: str = "voculinux"
|
||||
|
||||
VERIFICATION_STAMP_NAME: str = ".vocalinux_verified"
|
||||
LOG_FILE_PREFIX: str = "vocalinux_logs_"
|
||||
PORTAL_TOKEN_PREFIX: str = "vocalinux_"
|
||||
VERIFICATION_STAMP_NAME: str = ".voculinux_verified"
|
||||
LOG_FILE_PREFIX: str = "voculinux_logs_"
|
||||
PORTAL_TOKEN_PREFIX: str = "voculinux_"
|
||||
|
||||
ENV_FORCE_BACKEND: str = "VOCALINUX_FORCE_BACKEND"
|
||||
ENV_INJECT_MODIFIER_WAIT: str = "VOCALINUX_INJECT_MODIFIER_WAIT"
|
||||
ENV_YDOTOOL_KEY_DELAY: str = "VOCALINUX_YDOTOOL_KEY_DELAY"
|
||||
ENV_FORCE_BACKEND: str = "VOCULINUX_FORCE_BACKEND"
|
||||
ENV_INJECT_MODIFIER_WAIT: str = "VOCULINUX_INJECT_MODIFIER_WAIT"
|
||||
ENV_YDOTOOL_KEY_DELAY: str = "VOCULINUX_YDOTOOL_KEY_DELAY"
|
||||
|
||||
SITE_URL: str = "https://vocalinux.com"
|
||||
SITE_URL: str = "https://voculinux.com"
|
||||
|
||||
#: Files the rename ticket (#18) must flip. Checked by
|
||||
#: Previous install locations read once by the legacy importer. Never written.
|
||||
LEGACY_APP_DIR_NAME: str = "vocalinux"
|
||||
LEGACY_BUS_NAME: str = "com.vocalinux.Vocalinux"
|
||||
|
||||
#: Files the rename ticket (#18) flipped. Checked by
|
||||
#: ``tests/test_app_identity.py`` so the list cannot drift silently.
|
||||
RENAME_SURFACES: tuple[str, ...] = (
|
||||
"pyproject.toml",
|
||||
"vocalinux.desktop",
|
||||
"snap/gui/vocalinux.desktop",
|
||||
"voculinux.desktop",
|
||||
"snap/gui/voculinux.desktop",
|
||||
"snap/snapcraft.yaml",
|
||||
"packaging/flatpak/com.vocalinux.Vocalinux.desktop",
|
||||
"packaging/flatpak/com.vocalinux.Vocalinux.metainfo.xml",
|
||||
"packaging/flatpak/com.vocalinux.Vocalinux.yml",
|
||||
"packaging/aur/vocalinux-bin/vocalinux.desktop",
|
||||
"packaging/flatpak/com.voculinux.Voculinux.desktop",
|
||||
"packaging/flatpak/com.voculinux.Voculinux.metainfo.xml",
|
||||
"packaging/flatpak/com.voculinux.Voculinux.yml",
|
||||
"packaging/aur/voculinux-bin/voculinux.desktop",
|
||||
"web/src/app/page.tsx",
|
||||
"web/package.json",
|
||||
"README.md",
|
||||
|
||||