Running Scripts

KeyPath can run scripts when you press a key — shell scripts, AppleScript, Python, Ruby, Perl, or Lua. This lets you trigger custom automation from your keyboard: deploy a project, toggle system settings, control apps that don’t have keyboard shortcuts, or anything else a script can do.

Script execution is powerful, so it’s off by default and guarded by a confirmation system. This guide covers how to enable it, how to use it, and how the security model works.


Enabling script execution

Scripts are disabled by default. To turn them on:

  1. Open KeyPath Settings
  2. Go to the Script Execution section
  3. Toggle Enable Script Execution
  4. Confirm in the security dialog

Screenshot — Script Execution settings

The confirmation dialog explains what scripts can do — run commands, access files, and make network requests. This is a one-time decision; you can disable it again at any time.


Running your first script

Create a simple script:

#!/bin/bash
# ~/scripts/hello.sh
osascript -e 'display notification "Hello from KeyPath!" with title "Script"'

Make it executable:

chmod +x ~/scripts/hello.sh

Now trigger it from KeyPath using an action URI in your Kanata config:

(push-msg "script:~/scripts/hello.sh")

Or test it from Terminal:

open "keypath://script/~/scripts/hello.sh"

The first time a script runs, KeyPath shows a confirmation dialog with the script path. You can check “Don’t show again” to skip the dialog for future scripts.

Screenshot — First-run script confirmation


Supported script types

KeyPath detects the script type by file extension and runs it with the appropriate interpreter:

Extension Interpreter Notes
.sh /bin/bash Standard shell scripts
.bash /bin/bash Explicit Bash scripts
.zsh /bin/zsh Zsh scripts (macOS default shell)
.py /usr/bin/python3 Python 3 (probes common paths)
.rb /usr/bin/ruby Ruby (ships with macOS)
.pl /usr/bin/perl Perl (ships with macOS)
.lua /usr/local/bin/lua Lua (Homebrew or manual install)
.scpt Compiled AppleScript Pre-compiled AppleScript bundles
.applescript Text AppleScript Plain-text AppleScript source

Scripts without a recognized extension are executed directly (must be executable).


AppleScript integration

AppleScript is particularly useful because it can control other Mac apps:

-- ~/scripts/toggle-dark-mode.applescript
tell application "System Events"
    tell appearance preferences
        set dark mode to not dark mode
    end tell
end tell
;; In your Kanata config:
(push-msg "script:~/scripts/toggle-dark-mode.applescript")

More examples:

-- Open a specific URL in Safari
tell application "Safari" to open location "https://github.com"

-- Resize the frontmost window
tell application "System Events"
    tell process (name of first application process whose frontmost is true)
        set size of window 1 to {1200, 800}
    end tell
end tell

-- Toggle Do Not Disturb (macOS 12+)
do shell script "shortcuts run 'Toggle Focus'"

Practical examples

Deploy a project

#!/bin/bash
# ~/scripts/deploy.sh
cd ~/Projects/myapp
git push origin main
osascript -e 'display notification "Deployed!" with title "Deploy"'

Toggle Bluetooth

#!/bin/bash
# ~/scripts/toggle-bluetooth.sh
if blueutil --power | grep -q "1"; then
    blueutil --power 0
    osascript -e 'display notification "Bluetooth off" with title "Bluetooth"'
else
    blueutil --power 1
    osascript -e 'display notification "Bluetooth on" with title "Bluetooth"'
fi

Open a project in your editor

#!/bin/bash
# ~/scripts/open-project.sh
open -a "Visual Studio Code" ~/Projects/myapp

Quick note to clipboard

#!/usr/bin/env python3
# ~/scripts/timestamp-clip.py
import subprocess, datetime
ts = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
subprocess.run(["pbcopy"], input=ts.encode())

The URI format

Two equivalent ways to reference a script:

Context Syntax Example
Kanata config Shorthand script:~/scripts/hello.sh
Deep link Full URI keypath://script/~/scripts/hello.sh

Tilde (~) is expanded to your home directory. Paths with spaces work when URL-encoded in the full URI format.


Security model

Script execution has three layers of protection:

1. Global toggle

Script execution is off by default. Nothing runs until you explicitly enable it in Settings. You can disable it at any time to block all script execution instantly.

2. First-run confirmation

The first time any script runs, KeyPath shows a confirmation dialog:

  ┌─────────────────────────────────────────────────┐
  │  ⚠️  Script Execution                           │
  │                                                  │
  │  ~/scripts/hello.sh                              │
  │                                                  │
  │  This script can:                                │
  │  • Execute system commands                       │
  │  • Read and write files                          │
  │  • Access the network                            │
  │  • Control other applications                    │
  │                                                  │
  │  ☐ Don't show this warning again                 │
  │                                                  │
  │          [ Cancel ]  [ Run Script ]              │
  └─────────────────────────────────────────────────┘

Check “Don’t show again” only if you trust all scripts you’ll run. This bypasses the dialog for future scripts.

3. Execution log

KeyPath logs every script execution — path, timestamp, success/failure, and any errors. View the log in Settings > Script Execution > View Execution Log.

Screenshot — Script execution log

What scripts can’t do

  • Scripts run with your user permissions — they can’t do anything you couldn’t do in Terminal
  • Scripts have a 60-second timeout — long-running processes are killed
  • Scripts don’t have access to KeyPath’s internal state beyond what the action URI system provides

Using scripts with keyboard shortcuts

The most common pattern: bind a script to a key on a navigation layer or through the Quick Launcher.

On a navigation layer

;; In your Kanata config, on the nav layer:
(push-msg "script:~/scripts/deploy.sh")

Through the CLI

# Trigger a script directly
open "keypath://script/~/scripts/hello.sh"

Through Shortcuts or Siri

Use the “Send KeyPath Action” Shortcut with the URI keypath://script/~/scripts/hello.sh.