Hooks: run commands on record start and stop
Run your own shell commands when Vibe Typer starts and stops recording, saved per operating system and kept on the device you created them on.
A hook is a shell command Vibe Typer runs for you at one of two moments: just before recording starts, or just after it stops. Auto System Mute already handles your speakers. Hooks handle everything a volume control cannot reach.
Common uses:
playerctl pauseandplayerctl play, to pause a media player properly rather than muting it.- A
curlcall to a home automation endpoint, to turn a light on while you talk. - Setting a status in a chat app, or muting a hardware mixer.
Adding a hook
Open Settings, then Hooks, and choose Add hook. Each hook has four parts:
- Name. Optional, for your own reference in the list.
- Trigger. Either Before recording starts or After recording stops.
- Command. Anything your shell can run, for example
curl -X POST localhost:8080/mute. - Enabled. Turn a hook off without deleting it.
Test runs the command immediately so you can check it before relying on it mid-dictation.
How commands run
Commands go through your platform's default shell: /bin/sh -c on Linux and macOS, cmd.exe /c on Windows. They run as your user, with your permissions, and inherit your environment.
Vibe Typer sets one extra environment variable, VIBETYPER_HOOK, to beforeStart, afterStop or test, so a single script can branch on which moment fired it. Nothing else is passed. Your transcript and your audio are never handed to a hook.
Each command is bounded by a timeout, five seconds by default. Before-start hooks run in parallel and Vibe Typer waits for all of them before it captures audio, so a hook that pauses your music finishes first. After-stop hooks fire and are not waited on.
Output is ignored. A non-zero exit, a timeout or a command that does not exist is written to the log and nothing else happens. A failing hook never interrupts a recording or blocks your text.
To change the timeout, edit timeoutMs in your config.json. Values are clamped between 100ms and 60 seconds.
Hooks are saved per operating system
playerctl does not exist on Windows, and osascript does not exist on Linux. Every hook is tagged with the operating system it was created on and only runs there.
Hooks stay on the device you created them on. They are not synced with your account, so a hook you add on one machine never runs on another.
Troubleshooting
The command works in my terminal but not as a hook. Hooks run through /bin/sh, not the interactive shell you normally use, so aliases, functions and anything sourced from .zshrc or .bashrc are not available. Use the full path to the binary.
Nothing happens and there is no error. Hook output is discarded by design. Use the Test button, which shows the result, or have the command write to a file so you can see what it did.
The hook runs late. After-stop hooks are not waited on, so they run alongside insertion rather than before it. If the ordering matters, use a before-start hook.