Documentation
Actions YAML reference
Schema, placeholders, action types, and the shell allowlist.
Every voice action is one YAML file in ~/Library/Application Support/com.techguider.wisspa/actions/. The folder is file-watched: save a file and the registry reloads — no restart. The 14 defaults are seeded on first launch; browse them on the registry page.
Full schema
id: screenshot # unique id (filename should match)
name: "Interactive Screenshot to Clipboard"
description: "Triggers macOS interactive screenshot, copies result to clipboard"
triggers: # spoken phrases, matched exactly then fuzzily
- "screenshot"
- "take a screenshot"
- "screen grab"
type: shell # shell | applescript | open_url | open_app | keystroke
command: "screencapture -i -c" # what runs — meaning depends on type
working_dir: null # optional, shell only
requires_permissions: # checked before firing, with a clear error
- screen_recording
destructive: false # true = flagged as destructive in the UI
success_feedback: "Screenshot captured to clipboard"
failure_feedback: "Screenshot failed"
enabled: true # false = loaded but never matches
Matching rules
Your transcript is matched against every enabled action's triggers:
- Exact match first — longest trigger wins, so "search github for X" beats "search".
- Fuzzy pass — small Levenshtein distance (≤ 3) to tolerate transcription wobbles. Deliberately conservative: a near-miss doesn't fire, it just tells you nothing matched.
Action types
type |
command is… |
Example |
|---|---|---|
shell |
a shell command | screencapture -i -c |
applescript |
AppleScript source | tell application "System Events" to key code 123 |
open_url |
a URL to open in the default browser | https://github.com/search?q={query} |
open_app |
an app name to launch/focus | Calendar |
keystroke |
a key combo to simulate | cmd+v |
Placeholders
Filled at the moment you speak, before the command runs:
{query}— everything you said after the trigger phrase ("search github for tauri" →tauri). Percent-encoded automatically inopen_url.{clipboard}— current clipboard text.{selected_text}— the text you had selected.{active_app}— the frontmost app's name.
The shell allowlist
Shell commands are validated at load and rejected if they contain sudo, rm -rf, dd, or piped curl/wget execution. A rejected action shows up as invalid in Settings → Actions with the reason — the rest of the registry keeps working. Voice-activated rm -rf / is a genre of disaster we'd rather not enable.
Permissions and destructive flags
requires_permissions— declareaccessibility,screen_recording,automation, ormicrophone. Wisspa checks the grant before firing and tells you exactly which one is missing instead of failing silently.destructive: true— for anything that closes windows, kills processes, or locks things. It doesn't add a prompt; it marks the action clearly in the UI so you know which ones bite.
An example of your own
"Mute my mic" as a new file mute_audio.yaml:
id: mute_audio
name: "Mute system audio"
description: "Sets output volume to zero"
triggers:
- "mute audio"
- "mute my audio"
type: applescript
command: "set volume with output muted"
requires_permissions:
- automation
destructive: false
success_feedback: "Audio muted"
failure_feedback: "Couldn't mute audio"
enabled: true
Save it in the actions folder and say "mute audio" — it's live that second.