{ config, lib, pkgs, ... }: # Source: https://github.com/Lykos153/numen-nix with lib; let cfg = config.services.numen; in { options.services.numen = { enable = mkOption { type = types.bool; default = false; description = '' Enables Numen Voice Control. Only available to Users in Group "input". ''; }; numenPkg = mkOption { type = types.package; default = pkgs.kb-one.numen; }; modelPkg = mkOption { type = types.package; default = pkgs.kb-one.vosk-model-small-en-us; description = '' Vosk model to be loaded by numen. Overrides modelPkg! ''; }; dotoolPkg = mkOption { type = types.package; default = pkgs.kb-one.dotool; }; autoStart = mkOption { type = types.bool; default = true; }; phrases = mkOption { type = types.listOf types.path; default = [ ]; description = '' Phrases to be loaded by numen. If empty, the default phrases are used. ''; }; extraArgs = mkOption { type = types.singleLineStr; default = ""; description = '' Additional arguments to be passed to numen. ''; }; dotoolXkbLayout = mkOption { type = types.singleLineStr; default = "en"; description = '' The XKB keyboard layout that should be used by dotool. ''; }; }; config = mkIf cfg.enable { # System Configuration environment.systemPackages = [ cfg.numenPkg cfg.dotoolPkg cfg.modelPkg ]; services.udev.extraRules = '' KERNEL=="uinput", GROUP="input", MODE="0660", OPTIONS+="static_node=uinput" ''; # Enable AutoStart Service systemd.user.services.numen = mkIf cfg.autoStart { description = "Numen voice control"; after = [ "graphical-session-pre.target" ]; partOf = [ "graphical-session.target" ]; wantedBy = [ "graphical-session.target" ]; environment = { DOTOOL_XKB_LAYOUT = "${cfg.dotoolXkbLayout}"; NUMEN_MODEL = "${cfg.modelPkg}/usr/share/vosk-models/small-en-us/"; }; serviceConfig.ExecStart = "${cfg.numenPkg}/bin/numen ${cfg.extraArgs} ${lib.strings.concatStringsSep " " cfg.phrases}"; }; }; }