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 synced to your account.
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, so a single shared list would break the moment you signed in on a second machine. Every hook is tagged with the operating system it was created on and only runs there.
Hooks still sync with your account. On each device the Hooks screen shows the hooks for that operating system as a normal editable list, and any hooks you saved on your other operating systems below, under On your other devices. Those are shown read-only, as a record of what you have set up elsewhere. They will not run on the machine you are looking at.
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.