Custom Commands
Send final VoiceInk text to your own local workflow.
What Custom Commands Do
Custom Command is an output mode. It controls what happens after VoiceInk has the final text.
Before the command runs, the Mode can still use transcription settings, paragraph formatting, word replacements, AI Enhancement, prompts, and context. Custom Command receives the final text that VoiceInk is ready to deliver.
Use it when pasting is not enough and you want VoiceInk to hand the text to your own local workflow.
What You Can Build
Custom Commands can do anything a local non-interactive shell command can do within your macOS user permissions and the command timeout.
Common uses:
| Use case | What the command does |
|---|---|
| Custom paste behavior | Transform the final text, copy it to the clipboard, paste it, press another key, or move focus. |
| Notes and journals | Append dictation to a Markdown file, daily note, task list, log, or project file. |
| Search and lookup | Open a web search, documentation search, map, issue tracker, or internal URL using the dictated text. |
| Local scripts | Pass the text to your own shell, Python, Node, Ruby, or other local script. |
| App automation | Use tools such as open, osascript, pbcopy, or installed CLIs to control apps. |
| Webhooks and APIs | Use tools such as curl to send the text to a service you choose. |
If your command sends text to a web service, that service receives the text. VoiceInk only runs the command you configured.
What VoiceInk Sends
VoiceInk sends the same final text in two ways:
| Input | Use it when |
|---|---|
| Standard input | The next command reads text from stdin. |
$VOICEINK_TRANSCRIPT | You want the text inside a shell variable, argument, or pipeline. |
Examples:
cat > "$HOME/Desktop/voiceink.txt"printf "%s" "$VOICEINK_TRANSCRIPT" | pbcopyThe text is UTF-8. Quote $VOICEINK_TRANSCRIPT so spaces, punctuation, and line breaks are preserved.
What Final Text Means
Custom Command receives the Mode's final deliverable text:
- If AI Enhancement is off, it receives the transcript after VoiceInk formatting and word replacements.
- If AI Enhancement runs successfully, it receives the enhanced text.
- If AI Enhancement is skipped or fails, it receives the non-enhanced final transcript.
Custom Command does not receive the audio file, raw model tokens, prompt messages, selected text, clipboard text, or screen text directly. If you need context to affect the command output, use a prompt and Context Awareness so VoiceInk includes that context while producing the final text.
How It Runs
VoiceInk runs your command locally.
| Detail | Behavior |
|---|---|
| Shell | /bin/zsh -lc |
| Timeout | 10 seconds |
| Permissions | Same macOS user permissions as VoiceInk. |
| Recorder | The recorder is dismissed before the command starts. |
| Standard input | Final text is written to stdin, then stdin is closed. |
| Environment | VoiceInk passes $VOICEINK_TRANSCRIPT plus common shell variables. |
| Exit code | 0 means success. A non-zero exit code is treated as command failure. |
stdout and stderr | Captured for diagnostics. They are not pasted into the active app. |
VoiceInk tries to use your shell PATH. If a command is not found, use an absolute path such as /opt/homebrew/bin/tool or /Users/you/bin/script.
Available Variables
VoiceInk passes these environment values when available:
| Variable | Meaning |
|---|---|
$VOICEINK_TRANSCRIPT | The final text from the Mode. |
$HOME | Your home folder. |
$USER | Your macOS user name. |
$LOGNAME | Your login name. |
$SHELL | Your shell path, defaulting to /bin/zsh. |
$TMPDIR | A temporary directory. |
$PATH | Command search path discovered from your shell when possible. |
$LANG, $LC_ALL, $LC_CTYPE | Locale values when available. |
Important Limits
- Custom Command is an output mode. It decides delivery; it does not change the saved transcript by returning text on stdout.
- The command runs only after VoiceInk has a completed transcription result to deliver.
- Auto Send applies only to Paste output, not Custom Command output.
- The command must not require interactive input.
- The command must finish within 10 seconds. If it times out, VoiceInk stops the command process. For longer work, start your own background process and exit quickly.
- If you want the result pasted, your command must copy or paste it itself.
- If the command is empty, the Mode cannot be saved.
Built-In Templates
The command menu includes starter templates:
| Template | What it does |
|---|---|
| Paste and Press Tab | Copies the final text, pastes it, then presses Tab. |
| Lowercase and Paste | Lowercases the final text, copies it, then pastes it. |
| Remove Trailing Period and Paste | Removes one final period before pasting. |
| Append to Journal | Adds the final text to ~/Documents/VoiceInk/journal.md. |
| Search Web | Opens a Google search for the final text. |
Templates are examples. You can replace them with any command that follows the rules above.
Examples
Copy the final text:
printf "%s" "$VOICEINK_TRANSCRIPT" | pbcopyLowercase, copy, and paste:
printf "%s" "$VOICEINK_TRANSCRIPT" | tr '[:upper:]' '[:lower:]' | pbcopy
osascript <<'APPLESCRIPT'
tell application "System Events"
keystroke "v" using command down
end tell
APPLESCRIPTAppend to a note:
mkdir -p "$HOME/Documents/VoiceInk"
printf -- "- %s\n" "$VOICEINK_TRANSCRIPT" >> "$HOME/Documents/VoiceInk/notes.md"Open a search:
query=$(printf "%s" "$VOICEINK_TRANSCRIPT" | LC_ALL=C od -An -tx1 -v | tr -d ' \n' | sed 's/../%&/g')
open "https://www.google.com/search?q=$query"Pass text to your own script as an argument:
/Users/you/bin/handle-voiceink "$VOICEINK_TRANSCRIPT"Pass text to your own script through stdin:
/Users/you/bin/handle-voiceink-from-stdinSend text to an API you control:
printf "%s" "$VOICEINK_TRANSCRIPT" | curl -sS -X POST "https://example.com/voiceink" \
-H "Content-Type: text/plain; charset=utf-8" \
--data-binary @-Good Practices
- Start with a built-in template, then edit it.
- Use absolute paths for your own scripts and uncommon command-line tools.
- Quote variables.
- Keep commands fast and non-interactive.
- Test with harmless text before using it in an important Mode.
- Remember that your command controls the side effect. VoiceInk only supplies the final text and runs the command.