numen(1)

πŸ“¦ version 0.7, in alpine 3.24

🌸 NUMEN(1) β€” the voice control glow-up 🌸

okay bestie, so you know how there's a whole manual page for this thing called numen? Yeah. That's what this is. It lives in the General Commands Manual section (that's the (1) part, iykyk) and it's literally voice control for handsfree computing. No keyboard, no mouse, just you and your gorgeous little voice. πŸ’…


✨ SYNOPSIS ✨

numen [--gadget|--uinput|--x11] [--mic=NAME] [FILE...]
numen --help

that's it. that's the whole vibe check. 🫢


πŸ’– DESCRIPTION πŸ’–

numen reads phrases and actions from one or more files, and then β€” this is the main character moment β€” it performs the actions when you say their phrases. Iconic behavior, honestly.

With no arguments, numen uses the default phrases in the /etc/numen/phrases/ directory, unless you've put files ending with .phrases in the $XDG_CONFIG_HOME/numen/phrases/ directory. (And $XDG_CONFIG_HOME is ~/.config unless set otherwise β€” don't forget, bestie πŸ’œ)

There's also the numenc command to trigger actions programmatically. So like, if you don't feel like talking, you don't have to. Slay either way.


πŸ¦‹ DOTOOL AND KEYBOARD LAYOUTS πŸ¦‹

The default handler uses the dotool command to simulate input anywhere β€” X11, Wayland, TTYs, the whole multiverse β€” but it usually requires your user to be in group input (see dotool --help for the deets).

Now, if you use a non-us-qwerty keyboard layout, you can set the environment variables DOTOOL_XKB_LAYOUT and DOTOOL_XKB_VARIANT to have dotool simulate the right keys. For example, if you use the French fr layout:

DOTOOL_XKB_LAYOUT=fr numen

oui oui, keyboard go brrr πŸ₯–βœ¨


πŸŽ€ OPTIONS πŸŽ€

  • --audio=FILE β€” Specify an audio file to use instead of the microphone. Heads up though: this isn't for normal use, and the correct audio format depends on the speech recognition model. (So like, don't just throw any random mp3 at it, bestie 😭)
  • --audiolog=FILE β€” Write the audio to FILE while it's recorded. Great for spying on your own mic. Self-care.
  • -h, --help β€” Print help and exit. The classic.
  • --gadget β€” Simulate the input over USB using the gadget command (https://git.sr.ht/~geb/gadget). Extremely hardware-core of you.
  • --uinput β€” Simulate the input system-wide using the dotool command (see the section above). This is the default, so it's basically the hometown fave.
  • --list-mics β€” List audio devices and exit. The same as arecord -L.
  • --mic=AUDIO_DEVICE β€” Specify the audio device. Like arecord -D. Pick your fave.
  • --phraselog=FILE β€” Write phrases to FILE while they're performed. Very "not me narrating my own life".
  • --verbose β€” Show what is being used. Give the people (you) some transparency πŸ’–
  • --version β€” Print the version and exit.
  • --x11 β€” Simulate the input for X11 using the xdotool and xset commands. Retro. Vintage. X11 core.

🌈 CONFIGURATION 🌈

Phrase files consist of lines mapping phrases to actions. The format is:

[@TAG...] PHRASE:ACTION

That is, there can be zero or more "tags" starting with @, then the phrase, then a : and the action. If a line ends with a backslash, the next line is taken as another action. Empty lines and lines starting with # are ignored. So go ahead and comment your heart out, gorgeous.

Phrases with words unknown to the speech recognition model are ignored with a warning. Like, "sorry, don't know her." πŸ’€

πŸ’… ACTIONS πŸ’…

  • press [CHORD...] β€” Simulate each CHORD. For example, to cycle round splits in Vim:
switch: press ctrl+w w

The key names are the XKB key names which you can find with dotool --list-x-keys. The modifiers are super, ctrl, alt and shift.

  • type TEXT β€” Simulate typing TEXT. ASMR fr.
  • mod super/ctrl/alt/shift β€” Enable a modifier for the next press.
  • mod clear β€” Clear all modifiers. Reset era.
  • caps on/off β€” Enable/disable Caps Lock. Use responsibly. (or don't 🫢)
  • mouseto X Y β€” Teleport the cursor to X Y, where X and Y are percentages between 0.0 and 1.0. literally teleportation.
  • mousemove X Y β€” Move the cursor relative to its current position.
  • click left/middle/right β€” Simulate a mouse click. click click πŸ’…
  • wheel AMOUNT β€” Simulate a (vertical) mouse wheel. A positive AMOUNT is up, negative is down.
  • hwheel AMOUNT β€” Simulate a horizontal mouse wheel. A positive AMOUNT is right, negative is left.
  • stick on β€” Make presses not keyup, like holding down a key at a time. If already sticking, keyup but keep sticking.
  • stick off β€” Keyup and stop sticking. Closure, finally.
  • repeat TIMES β€” Repeat the previous click, mousemove, mouseto, pen, press, run, type, wheel or hwheel however many TIMES.
  • run COMMAND β€” Run a shell command. For example:
hi: run notify-send "Greetings, I'm a notification!"
  • pen COMMAND β€” Type the output of a shell command. For example, to type the date:
date: pen date +%D
  • eval COMMAND β€” Perform the output of a shell command as actions. For example, to backspace a transcription:
ditch: eval "$NUMEN_STATE_DIR/transcripts" | sed 's/./ BackSpace/g; s/^/press/; q'
  • set ENV_VAR COMMAND β€” Set an environment variable to the output of a shell command.
  • load [FILE...] β€” Switch to different phrase files, or pause numen by loading no files. For example, you can pause and resume numen programmatically using the numenc command:
$ echo load | numenc
...
$ echo load /etc/numen/phrases/*.phrases | numenc
  • handler gadget/uinput/x11 β€” Change between the --gadget, --uinput and --x11 modes. mid-sentence mode switch, we love to see it.
  • keydelay MILLISECONDS/reset β€” Set the time between press keys.
  • keyhold MILLISECONDS/reset β€” Set the time press keys are held.
  • typedelay MILLISECONDS/reset β€” Set the time between type/pen keys.
  • typehold MILLISECONDS/reset β€” Set the time type/pen keys are held.

🏷️ TAGS 🏷️

Tags have phrases act specially. lil personality modifiers, basically.

  • @cancel β€” Cancel the preceding phrases. never happened. gaslight gatekeep girlboss.
  • @transcribe β€” Do literal speech recognition until the next silence, record the results in $NUMEN_STATE_DIR/transcripts, and only then perform the action. For example, to type the top result:
@transcribe scribe: pen head -n 1 $NUMEN_STATE_DIR/transcripts
  • @gadget @uinput @x11 β€” If a phrase is tagged with any of these, ignore it unless numen was started in one of their modes. exclusive behavior, honestly.

⭐ SPECIAL PHRASES ⭐

The special phrase <complete> is performed after each sentence is performed. For example, to turn off Caps Lock at the end of each sentence:

<complete>: caps off

In addition to speech, numen can recognize a few particular noises nearly instantaneously. They are too trigger-happy for most uses, but good for playing games with a handful of carefully chosen words. Each noise has a special phrase for the beginning and end of its detection. They are:

  • <blow-begin> and <blow-end> β€” Blowing into the microphone. 🌬️
  • <hiss-begin> and <hiss-end> β€” SSSS! 🐍
  • <shush-begin> and <shush-end> β€” SHHH! 🀫

The environment variable NUMEN_NOISE_THRESHOLD adjusts the required energy for the noises (especially blowing). so if it's being too sensitive, you can turn down the drama.


🧚 ENVIRONMENT VARIABLES 🧚

numen can be tweaked by some environment variables:

  • NUMEN_NOISE_THRESHOLD as noted above.
  • NUMEN_KEY_DELAY, NUMEN_KEY_HOLD, NUMEN_TYPE_DELAY and NUMEN_TYPE_HOLD are like their corresponding actions but at startup. set it and forget it, bestie.
  • NUMEN_SHELL sets the shell used for shell commands, instead of /bin/sh.

πŸ“ STATE FILES πŸ“

numen exposes some of its state in files in the $NUMEN_STATE_DIR directory. numen will set $NUMEN_STATE_DIR to the default ($XDG_STATE_HOME/numen) if not set otherwise, for convenience in actions. (And $XDG_STATE_HOME is ~/.local/state unless set otherwise.) so thoughtful of it πŸ₯Ή

  • $NUMEN_STATE_DIR/handler contains gadget, uinput or x11 depending on the mode.
  • $NUMEN_STATE_DIR/mods contains the state of the modifier keys.
  • $NUMEN_STATE_DIR/phrase contains the previous phrase.
  • $NUMEN_STATE_DIR/transcripts contains the results of the @transcribe tag.

πŸ”₯ DIFFERENT MODELS AND LANGUAGES πŸ”₯

Properly supporting/testing different speech recognition models and spoken languages is on the todo list, but numen should work with any of the small models from https://alphacephei.com/vosk/models. Use the environment variable NUMEN_MODEL to specify the path to the model directory. multilingual queen πŸ‘‘


πŸ’œ EXAMPLES πŸ’œ

Run numen with the default phrases:

$ numen /etc/numen/phrases/*.phrases

There shouldn't be any output but you should be able to type hey by saying "hoof each yank". You can also try transcribing a sentence after saying "scribe", and terminate it by pressing Ctrl+c (a.k.a "troy cap"). no cap, that's literally what it's called.

Check the microphone:

$ timeout 5 numen --verbose --audiolog=me.wav
$ aplay me.wav

Run numen printing the phrases while they're performed:

$ numen --phraselog=/dev/stdout

πŸ‘‘ AUTHOR πŸ‘‘

John Gebbie. the icon, the legend, the moment. πŸ’–


and that's the whole page, bestie!! brought to you by numen(1) from the General Commands Manual β€” this edition is dated 2026-10-14 β€” go forth and say things into the void, it'll type them for you πŸ«Άβœ¨πŸŽ€

πŸ“¦ where this page comes from