From 413b81c8b24a47fe9041aae1db5b5bf1a8a5c734 Mon Sep 17 00:00:00 2001 From: sommerfeld Date: Fri, 5 Jun 2026 11:05:58 +0100 Subject: feat(nix): migrate user-leaf tools to host profile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pull every pacman/AUR entry that is (1) packaged in nixpkgs and (2) free of tight system coupling out of meta/base.txt and into nix/host.nix. System coupling = setuid, /usr/lib/systemd/system unit, udev rule, /usr/share/dbus-1/services file, /usr/share/wayland-sessions entry, shared lib other pacman pkgs link, /etc/makepkg.conf reference, system fontconfig path, PAM, Qt plugin search path, or kernel/ firmware/bootloader touchpoint. User-scope systemd units are NOT coupling — nix drops them in ~/.nix-profile/share/systemd/user/ and systemd picks them up; the chezmoi-owned unit files that referenced /usr/bin/ paths are fixed in a follow-up commit. Wayland session: waybar, mako, fuzzel, wofi, swayidle, swayr, inhibridge, bemoji, wob, poweralertd, grim, slurp, wf-recorder, wtype, wl-clipboard, cliphist, imv, wl-mirror, playerctl, pulsemixer, ghostty. General CLIs: qrencode, torsocks, lshw, yt-dlp, streamlink, chezmoi, paru. GUI: sparrow. OCR: tesseract collapsed with .override { enableLanguages = [eng por] } — replaces tesseract + tesseract-data-eng + tesseract-data-por. STT: whisper-cpp.override { vulkanSupport = true; } plus an inline whisper-cpp-model-base derivation that fetches ggml-base.bin from the upstream huggingface mirror into ~/.nix-profile/share/whisper-cpp-models/. --- nix/host.nix | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 114 insertions(+), 10 deletions(-) diff --git a/nix/host.nix b/nix/host.nix index 96adfba..64a0555 100644 --- a/nix/host.nix +++ b/nix/host.nix @@ -1,29 +1,133 @@ { config, pkgs, lib, dotfilesRoot, ... }: # Arch host Home-Manager profile. Layered on top of `common.nix`; adds -# only host-specific concerns that don't make sense on the VM. +# only host-specific concerns that don't make sense on the VM (wayland +# session tools, Yubikey, host-only CLIs / GUIs). # # Dotfile deployment on the host is owned entirely by **chezmoi** (run # via `just apply` / `just sync`). Home-Manager here only installs # binaries and writes the host-only smartcard config below. +# +# Migration policy: a tool lives here iff nixpkgs ships a working +# equivalent AND it has no tight system coupling (no setuid, no +# /usr/lib/systemd/system unit, no udev rule, no system D-Bus +# activation, no /usr/share/wayland-sessions entry, no shared lib that +# other pacman pkgs link, no system fontconfig path, no PAM, no Qt +# plugin search path, no kernel/firmware/initramfs touchpoint). +# User-scope systemd units are NOT system coupling — nix drops them in +# ~/.nix-profile/share/systemd/user/ and systemd picks them up. +let + # Whisper.cpp base model — packaged inline because nixpkgs doesn't + # ship the .bin blobs. Sourced from the upstream huggingface mirror + # (same URL the AUR `whisper.cpp-model-base` uses). The dictate script + # at dot_local/bin/executable_dictate defaults to + # ~/.nix-profile/share/whisper-cpp-models/ggml-base.bin. + whisper-cpp-model-base = pkgs.stdenvNoCC.mkDerivation rec { + pname = "whisper-cpp-model-base"; + version = "1.0"; + src = pkgs.fetchurl { + url = "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.bin"; + hash = "sha256-YO1bw90U7qhWST0zQ0m0BXgt3K8AKNS130CINF+6Lv4="; + }; + dontUnpack = true; + installPhase = '' + runHook preInstall + install -Dm644 $src $out/share/whisper-cpp-models/ggml-base.bin + runHook postInstall + ''; + meta = with lib; { + description = "Whisper.cpp ggml-base.bin model (142 MB, multilingual)"; + homepage = "https://huggingface.co/ggerganov/whisper.cpp"; + license = licenses.mit; + platforms = platforms.all; + }; + }; +in { imports = [ ./common.nix ]; home.username = builtins.getEnv "USER"; home.homeDirectory = builtins.getEnv "HOME"; - # ── Thunderbird helpers (host only) ──────────────────────────────────────── - # external-editor-revived is the native-messaging host that lets the - # Thunderbird addon hand a composing draft to $EDITOR. We run TB as the - # org.mozilla.thunderbird flatpak; the AUR package would drag in system - # `thunderbird` as a hard dep, so we take it from nixpkgs here instead - # (the nix derivation has no mailer dep). The bridge wiring lives in - # run_onchange_after_deploy-tb-eer.sh.tmpl; it auto-detects the binary - # under ~/.nix-profile and the manifest gets relocated into the TB - # flatpak sandbox. home.packages = with pkgs; [ + # ── Thunderbird helpers ─────────────────────────────────────────────────── + # external-editor-revived is the native-messaging host that lets the + # Thunderbird addon hand a composing draft to $EDITOR. We run TB as the + # org.mozilla.thunderbird flatpak; the AUR package would drag in system + # `thunderbird` as a hard dep, so we take it from nixpkgs here instead + # (the nix derivation has no mailer dep). The bridge wiring lives in + # run_onchange_after_deploy-tb-eer.sh.tmpl; it auto-detects the binary + # under ~/.nix-profile and the manifest gets relocated into the TB + # flatpak sandbox. external-editor-revived + + # ── Wayland session: bars, launchers, notifiers, daemons ────────────────── + # Pure user-session GUIs/daemons — no system unit, no D-Bus activation + # file under /usr/share/dbus-1, no login-manager session entry. The + # corresponding user-scope systemd units live under + # dot_config/systemd/user/ and reference these binaries by bare name + # so $PATH resolves them out of ~/.nix-profile/bin. + waybar + mako + fuzzel + wofi # used by bemoji + mako-history.sh + swayidle + swayr # auto-tiling + window switcher + inhibridge # browser idle-inhibit bridge → systemd-inhibit + bemoji # emoji picker (wofi backend) + wob # volume/brightness OSD + poweralertd + + # ── Wayland: capture + clipboard + image viewing ───────────────────────── + grim + slurp + wf-recorder + wtype + wl-clipboard # wl-copy + wl-paste + cliphist # clipboard history (used by cliphist-{text,image} units) + imv + wl-mirror + + # ── Media control ──────────────────────────────────────────────────────── + playerctl # MPRIS over session bus + pulsemixer # TUI for PipeWire/PulseAudio + + # ── Terminal ───────────────────────────────────────────────────────────── + ghostty + + # ── General CLIs migrated off pacman ────────────────────────────────────── + qrencode + torsocks + lshw + yt-dlp + streamlink + + # chezmoi & paru — both are pure user CLIs. `paru` wraps pacman+makepkg + # but doesn't link them; it just shells out. bootstrap.sh installs a + # one-shot pacman `chezmoi` for the very first `chezmoi init --apply`, + # then `paru -Rns chezmoi paru` after the first nix-switch drops the + # pacman copies (the nix-profile copies on PATH take over). + chezmoi + paru + + # ── GUIs ───────────────────────────────────────────────────────────────── + # Bitcoin wallet. Pulls zulu25 + JavaFX (~300 MB closure) but the AUR + # build pulled the same JRE anyway. + sparrow + + # ── OCR ────────────────────────────────────────────────────────────────── + # Override merges eng + por language data into a single derivation, + # replacing three pacman packages (tesseract, tesseract-data-eng, + # tesseract-data-por). + (tesseract.override { enableLanguages = [ "eng" "por" ]; }) + + # ── Speech-to-text (dictate script) ────────────────────────────────────── + # whisper.cpp with Vulkan acceleration. `mainProgram = "whisper-cli"` + # matches the binary the dictate script invokes. The base model below + # is a separate derivation so we can drop the AUR `whisper.cpp-model-base`. + (whisper-cpp.override { vulkanSupport = true; }) + whisper-cpp-model-base ]; # ── Smartcard (Yubikey) ──────────────────────────────────────────────────── -- cgit v1.3.1