VoiceInk Docs
Modes

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 caseWhat the command does
Custom paste behaviorTransform the final text, copy it to the clipboard, paste it, press another key, or move focus.
Notes and journalsAppend dictation to a Markdown file, daily note, task list, log, or project file.
Search and lookupOpen a web search, documentation search, map, issue tracker, or internal URL using the dictated text.
Local scriptsPass the text to your own shell, Python, Node, Ruby, or other local script.
App automationUse tools such as open, osascript, pbcopy, or installed CLIs to control apps.
Webhooks and APIsUse 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:

InputUse it when
Standard inputThe next command reads text from stdin.
$VOICEINK_TRANSCRIPTYou want the text inside a shell variable, argument, or pipeline.

Examples:

cat > "$HOME/Desktop/voiceink.txt"
printf "%s" "$VOICEINK_TRANSCRIPT" | pbcopy

The 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.

DetailBehavior
Shell/bin/zsh -lc
Timeout10 seconds
PermissionsSame macOS user permissions as VoiceInk.
RecorderThe recorder is dismissed before the command starts.
Standard inputFinal text is written to stdin, then stdin is closed.
EnvironmentVoiceInk passes $VOICEINK_TRANSCRIPT plus common shell variables.
Exit code0 means success. A non-zero exit code is treated as command failure.
stdout and stderrCaptured 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:

VariableMeaning
$VOICEINK_TRANSCRIPTThe final text from the Mode.
$HOMEYour home folder.
$USERYour macOS user name.
$LOGNAMEYour login name.
$SHELLYour shell path, defaulting to /bin/zsh.
$TMPDIRA temporary directory.
$PATHCommand search path discovered from your shell when possible.
$LANG, $LC_ALL, $LC_CTYPELocale 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:

TemplateWhat it does
Paste and Press TabCopies the final text, pastes it, then presses Tab.
Lowercase and PasteLowercases the final text, copies it, then pastes it.
Remove Trailing Period and PasteRemoves one final period before pasting.
Append to JournalAdds the final text to ~/Documents/VoiceInk/journal.md.
Search WebOpens 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" | pbcopy

Lowercase, copy, and paste:

printf "%s" "$VOICEINK_TRANSCRIPT" | tr '[:upper:]' '[:lower:]' | pbcopy
osascript <<'APPLESCRIPT'
tell application "System Events"
    keystroke "v" using command down
end tell
APPLESCRIPT

Append 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-stdin

Send 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.