| name | talon |
| description | Use when working on Talon voice command projects — writing .talon files, .talon-list files, or Talon Python modules, AND when installing or deploying Talon scripts to the user's Talon directory. Provides file syntax, voice command rules, context matching, list definitions, Python API tips, local testing, and sandbox testing via talonbox. |
Talon Voice Command Development
Reference Documentation
For detailed syntax documentation, see bundled references:
references/talon-files.md — .talon file syntax, context headers, commands, actions, captures, settings, tags
references/talon-lists.md — .talon-list file format, overrides, named vs simple lists
references/misc-tips.md — REPL and logging usage, introspection functions (sim, mimic, actions.find/list, events.tail, registry inspection), and the Talon Python API (ui, clip, cron, screen, imgui, canvas, noise, fs modules)
Testing
Host REPL (read-only queries)
Use the host REPL only by piping one-shot commands into it for read-only queries — introspecting registries, testing command parsing with sim(), listing actions, etc. Do not open or rely on an interactive REPL session. Do NOT use the host REPL for testing behavioral changes that depend on specific application context.
- Mac:
~/.talon/bin/repl
- WSL:
talon-repl
- Simple query:
printf 'actions.list(\"user\")\n' | ~/.talon/bin/repl
- Import plus query:
printf 'from talon import ui; print(ui.active_app())\n' | ~/.talon/bin/repl
The raw REPL treats piped stdin as one Talon REPL input block, not as interactive lines entered one at a time. Do not pipe multiple top-level Python statements directly into it. Keep small queries to one statement; semicolon-separated simple statements work for imports plus a read-only query.
For a multiline host snippet, use a quoted heredoc and keep the code in one compound statement. An if True: block is a readable wrapper for read-only debugging snippets:
~/.talon/bin/repl <<'PY'
if True:
from talon import ui
print("active app", ui.active_app())
try:
print("focused", ui.focused_element())
except Exception as error:
print("focused ERROR", type(error).__name__, repr(error))
PY
On macOS the host REPL connects to ~/.talon/.sys/repl.sock. If a sandboxed command reports PermissionError: [Errno 1] Operation not permitted or says it could not open the REPL, rerun that REPL command outside the sandbox before assuming Talon is stopped.
talonbox (sandbox testing)
Use talonbox for tests that interact with the OS or with the user's Talon scripts — running mimic(), verifying side effects, capturing screenshots, or deploying scripts to a clean environment. It drives a macOS VM with a full Talon installation.
Run talonbox --help and talonbox <command> --help for usage details.
Default to a disposable, named clone for each test or experiment instead of reusing an existing VM. Clone golden to a readable, task-specific VM name, start that VM, run the experiment, then stop it when the task is complete:
talonbox clone golden test-clipboard-formatting
talonbox start test-clipboard-formatting
talonbox rsync -a ./ test-clipboard-formatting:/Users/lume/.talon/user/example/
talonbox mimic test-clipboard-formatting 'some voice command'
talonbox screenshot test-clipboard-formatting /tmp/test-clipboard-formatting.png
talonbox stop test-clipboard-formatting
Prefer bounded, token-efficient command output in diagnostics and examples.
Use names that describe the task well enough to recognize later, such as test-cursorless-snippets, debug-dictation-timeout, or experiment-list-overrides. If the task needs multiple independent attempts, create separate clones with distinct names.
Lifecycle rules:
- Prefer
talonbox clone golden <task-name> before starting a sandbox. clone requires golden to be stopped and the destination name to be unused.
- Use
talonbox start <task-name> only after choosing the clone to work in. start never clones, deletes, or resets the VM.
- Always run
talonbox stop <task-name> once the test or experiment is complete, even if the result is inconclusive. It is safe to run repeatedly.
- Do not delete the VM immediately after testing. Keep the stopped VM available for inspection until the user has approved the changes and the work has been committed.
- Only after user approval and a successful commit, clean up with
talonbox delete <task-name>. delete requires the VM to be stopped first.
- Use
talonbox list or talonbox status <task-name> when checking what sandboxes already exist or whether one is still running.
Local Development
Mac
- Repo locations: Talon repos live in
~/projects/ and are symlinked into ~/.talon/user/
- Auto-reload: Changes to
.talon and .py files are automatically reloaded within a few seconds
- Logs:
~/.talon/talon.log (very long — don't read the whole thing). Changed files appear as DEBUG [~] /path/to/file, with possible WARNING or ERROR lines afterwards
Deploying Changes with talon-install
After making changes to a Talon repo, run talon-install to update the symlink in ~/.talon/user/ so Talon picks up the changes. Must be run from within the git repo.
Usage: talon-install [--main] (--live | --snapshot)
Defaults:
- Main worktree (running from it, or using
--main): use --live
- Alternate worktree: use
--snapshot
Workflows:
-
Editing the main branch directly:
Run talon-install --live from the main worktree. The symlink points directly to the repo, so subsequent edits are picked up automatically.
-
Testing a feature branch in a worktree:
Run talon-install --snapshot from the alternate worktree. A snapshot copy is made so further edits don't cause partial-state loading in Talon. Run it again after each batch of changes.
-
Reverting to known-working state:
Run talon-install --main --live from any worktree of the repo. This points the symlink back at the main worktree, restoring stable behavior. Use this when a worktree's changes have broken something, then fix the issue and re-run talon-install --snapshot to test again.
Notes:
- The
cursorless-talon and cursorless-talon-dev symlinks are managed separately and are not affected by talon-install
- Snapshots exclude
.git/ and .venv/ to stay fast and small
- Only one snapshot per project is kept; old ones are cleaned up automatically
WSL
- Deploying changes: Run
sync-talon-repo to push the current repository to the Talon user directory in Windows
- Auto-reload: Talon takes a few seconds to load changed files after sync
- Logs:
/mnt/c/Users/james/AppData/Roaming/talon/talon.log (very long — don't read the whole thing). Changed files appear as DEBUG [~] c:\path\to\file, with possible WARNING or ERROR lines afterwards