Generate a command with AI

Clyde commands are simple JSON. That makes them unusually easy for AI to generate correctly. Describe your idea, get working code in seconds.

How JSON commands work

A command is a JSON file in ~/.clyde/user-commands/. AI can produce this reliably every time because the schema is small and predictable.

SCHEMA

my-command.json
{
  "id": "my-module",
  "displayName": "My Module",
  "description": "Commands for doing useful things.",
  "color": "blue",
  "icon": "star",
  "author": "your-github-username",
  "homepage": "https://yourapp.com",
  "registry": "https://github.com/ColorfulDots/clyde-registry",
  "version": "1.0.0",
  "tags": ["productivity", "utilities"],
  "commands": [
    {
      "name": "Open Something",
      "keywords": ["something", "open"],
      "executor": "urlScheme",
      "target": "https://example.com",
      "description": "Opens example.com"
    }
  ]
}

EXAMPLE

obsidian.json
{
  "id": "obsidian",
  "displayName": "Obsidian",
  "description": "Commands for your Obsidian vaults.",
  "color": "purple",
  "icon": "note.text",
  "author": "colorfulDots",
  "homepage": "https://obsidian.md",
  "registry": "https://github.com/ColorfulDots/clyde-registry",
  "version": "1.0.0",
  "tags": ["notes", "productivity"],
  "commands": [
    {
      "name": "Open Daily Journal",
      "keywords": ["journal", "daily", "obsidian"],
      "executor": "urlScheme",
      "target": "obsidian://daily",
      "description": "Open today's daily note in Obsidian"
    }
  ]
}

EXECUTOR TYPES

urlScheme

Opens a URL or deep link

obsidian://daily, https://github.com

shell

Runs a shell command

open -a Terminal, kill -9 $(lsof -ti:3000)

applescript

Runs AppleScript source

tell application "Finder" to empty trash

shortcut

Runs a Shortcuts.app shortcut by name

My Morning Routine

scriptReceiver

Runs a .sh script and renders its JSON response as an interactive result in Clyde

~/.clyde/user-scripts/pomodoro.sh

INSTALLING A JSON COMMAND

1
Save the file as my-command.json
2
Drop it into ~/.clyde/user-commands/
3
Open Clyde and run reload user-commands
4
Your new command is live—type its name or any keyword to trigger it

How shell scripts work

For interactive flows—dialogs, prompts, file pickers, multi-step logic—use a .sh script. The JSON command just points to it with executor: "shell".

THE USER SCRIPT

~/.clyde/user-scripts/search.sh
#!/bin/bash
query=$(osascript -e 'tell app "System Events"
  text returned of (display dialog "Search Google:" default answer "" with title "Clyde")
end tell')

[ -z "$query" ] && exit 0

encoded=$(python3 -c "import urllib.parse,sys; print(urllib.parse.quote(sys.argv[1]))" "$query")
open "https://www.google.com/search?q=$encoded"

THE JSON COMMAND

search.json
{
  "id": "search",
  "displayName": "Search",
  "description": "Interactive search commands.",
  "color": "blue",
  "icon": "magnifyingglass",
  "author": "your-github-username",
  "version": "1.0.0",
  "tags": ["search", "utilities"],
  "commands": [
    {
      "name": "Search Google",
      "keywords": ["search", "google"],
      "executor": "shell",
      "target": "bash ~/.clyde/user-scripts/search-google.sh",
      "description": "Ask for a query, open in Google"
    }
  ]
}

INSTALLING A SHELL SCRIPT COMMAND

1
Save the user script as ~/.clyde/user-scripts/my-script.sh
2
Make it executable: chmod +x ~/.clyde/user-scripts/my-script.sh
3
Save the JSON command pointing to it in ~/.clyde/user-commands/
4
Run reload user-commands in Clyde

scriptReceiver—interactive scripts

scriptReceiver is the most powerful executor type. Instead of running a command and moving on, it runs a .sh script and renders its JSON response as a full interactive result inside Clyde — with a status header, list rows, action buttons, and native notifications.

SHELL VS SCRIPTRECEIVER

Use shell when…

  • — One action, no feedback needed
  • — Opening an app or URL via a shell command
  • — A simple one-liner does the job

Use scriptReceiver when…

  • — You want to show a result in Clyde
  • — You need list rows, buttons, or multiple steps
  • — You want to fire a native notification from a script
  • — Your command has state (timers, toggles, sessions)

THE SCRIPT

~/.clyde/user-scripts/pomodoro.sh
#!/bin/zsh
ACTION="${1:-}"

case "$ACTION" in
  Pause)
    echo '{"title":"Paused","actions":[{"label":"Resume","command":""},{"label":"Stop","command":""}]}'
    ;;
  Resume)
    echo '{"title":"Running","output":"24:37 remaining","actions":[{"label":"Pause","command":""},{"label":"Stop","command":""}]}'
    ;;
  Stop)
    rm -f ~/.clyde/state/pomodoro.json
    echo '{"title":"Stopped","output":"Session ended","notify":"Pomodoro complete. Take a break."}'
    ;;
  *)
    echo '{"title":"Pomodoro—25:00","output":"Focus session ready","actions":[{"label":"Start","command":""},{"label":"Stop","command":""}]}'
    ;;
esac

THE JSON COMMAND

pomodoro.json
{
  "name": "Pomodoro",
  "keywords": ["pomodoro", "focus", "timer"],
  "executor": "scriptReceiver",
  "target": "~/.clyde/user-scripts/pomodoro.sh",
  "description": "Start and manage a Pomodoro timer"
}

RESPONSE FIELDS (all optional)

title
string

Shown as the result header

output
string

Main body text

error
string

Marks the result as failed, shown as error text

notify
string

Fires a native macOS notification

items
array

List rows: title (required), subtitle, badge, warning

actions
array

Buttons—label is shown in Clyde and passed as $1 on tap

Note: stdout must be a single clean JSON object. Use stderr for debug output (echo "debug" >&2). Any extra stdout will break structured rendering and fall back to plain text.

INSTALLING A SCRIPTRECEIVER COMMAND

1
Save the script as ~/.clyde/user-scripts/my-script.sh
2
Make it executable: chmod +x ~/.clyde/user-scripts/my-script.sh
3
Save the JSON command with executor: "scriptReceiver" and target pointing to the script
4
Run reload user-commands in Clyde

State persistence

Clyde does not persist state between runs. Write to ~/.clyde/state/ or /tmp/ if your script needs pause/resume/status behavior.

Keep it fast

Clyde waits synchronously for your script to exit. For long-running work, fork immediately (nohup ... &) and return a status response right away.

Real shell script examples

These user scripts are in the registry. Drop them in ~/.clyde/user-scripts/ and reference them from a JSON command.

Search Google

Prompts for a query and opens it in Google.

search-google.sh

#!/bin/bash
query=$(osascript -e 'tell app "System Events" to text returned of (display dialog "Search Google:" default answer "" with title "Clyde")')
[ -z "$query" ] && exit 0
encoded=$(python3 -c "import urllib.parse,sys; print(urllib.parse.quote(sys.argv[1]))" "$query")
open "https://www.google.com/search?q=$encoded"

Kill Port

Asks for a port number and kills whatever process is on it.

kill-port.sh

#!/bin/bash
port=$(osascript -e 'tell app "System Events" to text returned of (display dialog "Kill process on port:" default answer "3000" with title "Clyde")')
[ -z "$port" ] && exit 0
pid=$(lsof -ti ":$port")
if [ -z "$pid" ]; then
  osascript -e "display notification "Nothing running on port $port" with title "Clyde""
else
  kill -9 $pid
  osascript -e "display notification "Killed process on port $port" with title "Clyde""
fi

Git Commit & Push

Prompts for a commit message, then adds, commits, and pushes.

git-commit-push.sh

#!/bin/bash
dir=$(osascript -e 'tell app "Finder" to POSIX path of (target of front window as alias)' 2>/dev/null || echo "$HOME")
cd "$dir" || exit 1
message=$(osascript -e 'tell app "System Events" to text returned of (display dialog "Commit message:" default answer "" with title "Clyde")')
[ -z "$message" ] && exit 0
git add -A && git commit -m "$message" && git push
osascript -e "display notification "Pushed: $message" with title "Clyde""

New Project

Names a new project, scaffolds a folder, inits git, opens in VS Code.

new-project.sh

#!/bin/bash
name=$(osascript -e 'tell app "System Events" to text returned of (display dialog "Project name:" default answer "" with title "Clyde")')
[ -z "$name" ] && exit 0
mkdir -p "$HOME/Projects/$name" && cd "$HOME/Projects/$name"
git init -q && echo "# $name" > README.md && echo ".DS_Store" > .gitignore
git add -A && git commit -q -m "init"
if command -v code &>/dev/null; then code "$HOME/Projects/$name"; else open "$HOME/Projects/$name"; fi
osascript -e "display notification "Created $name in ~/Projects" with title "Clyde""

Inspiration

Not sure what to build? Click any idea to pre-fill the generator above.

Give back to the community

Built something useful? The registry is just a GitHub repo—your command is one pull request away from being available to every Clyde user.

2
Add your .json file to official/user-commands/
3
If you have a .sh script, add it to official/user-scripts/ and reference it in your JSON
4
Open a pull request—that's it