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

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

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

Refs #18
This commit is contained in:
soubarnak
2026-11-06 01:29:39 +05:30
parent c565e6d946
commit ea7be5f111
251 changed files with 2449 additions and 1991 deletions
+1 -1
View File
@@ -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"
}
+25 -25
View File
@@ -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"
+2 -2
View File
@@ -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
+7 -7
View File
@@ -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 -5
View File
@@ -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
+2 -2
View File
@@ -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
+9 -9
View File
@@ -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")"
+19 -19
View File
@@ -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: ../..
+3 -3
View File
@@ -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> ·
+22 -22
View File
@@ -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 -------------------------------------------------------------
+7 -7
View File
@@ -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:
+6 -6
View File
@@ -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}"
+10 -10
View File
@@ -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; }
];
};
};
+6 -6
View File
@@ -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.";
};
};
+9 -9
View File
@@ -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.";
};
};
+10 -10
View File
@@ -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;
};
}
+1 -1
View File
@@ -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";