Cherri is a programming language that compiles to Apple Shortcuts. When writing Cherri code, you're essentially creating iOS/macOS Shortcuts using a more traditional programming syntax.
- Comments: Use
/* */for block comments,//for line comments - Variables: Use
@varName = valueto declare variables - Constants: Use
const varName = valuefor constants - Strings: Can use double quotes
"text"or template literals with variables"{varName}"
Actions are the core building blocks - they map directly to Shortcut actions:
// Display an alert
alert("Message", "Title")
// Show output
show("Text to display")
// Get text input
@userInput = askText("Enter text:", "Default value")
if condition {
// code
} else {
// code
}
// For each item in list (CORRECT syntax)
for item in list {
alert(item)
}
// Repeat n times
repeat 5 {
alert("{RepeatIndex}")
}
// Repeat with index variable
repeat i for 5 {
alert("Index: {i}")
}
menu "Choose an option:" {
item "Option 1":
alert("You chose option 1")
item "Option 2":
alert("You chose option 2")
}
#include 'actions/scripting'
@list = list("Option 1", "Option 2", "Option 3")
@chosenItem = chooseFromList(list, "Choose an item")
- Use colon
:after item name, NOT curly braces{} - Menu prompts can be variables or string literals
- Item labels can be variables or string literals
- Each item can have multiple action lines
- Variables assigned in menu items persist after menu execution
@name = "World"
@greeting = "Hello, {name}!"
alert(greeting)
// Text operations
@upper = changeCase(greeting, "uppercase")
@replaced = replaceText("World", "Cherri", greeting)
@items = ["apple", "banana", "cherry"]
repeatEach fruit in items {
alert(fruit)
}
@name = askText("What's your name?")
@age = askNumber("What's your age?")
alert("Hello {name}, you are {age} years old")
Use #include to split code across files:
#include "other_file.cherri"
#define color red
#define glyph star
#define name "My Shortcut"
Define reusable actions:
action greet(text name) {
alert("Hello, {name}!")
}
// Use it
greet("World")
- Start Simple: Begin with basic alert() or show() to test compilation
- Use Examples: Reference tests/*.cherri files for syntax patterns
- Check Action Definitions: Actions are defined in actions/*.cherri files
- Variable Syntax: Always use @ for variable assignment, not declaration
- String Interpolation: Use
"{varName}"to include variables in strings
- Wrong Alert Syntax:
alert(message, title)notalert(title, message) - Missing @: Variables need @ when assigned:
@var = value - Case Sensitivity: Cherri is case-sensitive
- Action Names: Many actions have specific names (e.g.,
askTextnotprompt)
- Build Command:
./cherri filename.cherri - Fast Iteration: Use
--skip-signflag during development to skip signing (much faster)- Development:
./cherri filename.cherri --skip-sign - Production:
./cherri filename.cherri(includes signing)
- Development:
- Debug Mode: Use
--debugor-dflag for detailed output - Output: Creates
.shortcutfile with same base name - Signing: Will attempt macOS signing, falls back to HubSign service (unless --skip-sign is used)
- Parse Errors: Usually syntax issues - check brackets, quotes
- Unknown Action: Action doesn't exist - check actions/*.cherri
- Type Errors: Wrong parameter types - check action definitions
- Variable Errors: Undefined variables - ensure @ is used correctly
alert(message, ?title)- Show alert dialogshow(text)- Display outputaskText(prompt, ?default)- Get text inputaskNumber(prompt, ?default)- Get number inputnothing()- Clear outputstop()orexit()- Stop shortcutcomment(text)- Add comment
@var = value- Assign variableconst name = value- Declare constant{varName}- Use in strings- Global variables:
Ask,Clipboard,CurrentDate,ShortcutInput,RepeatIndex,RepeatItem
text- String typenumber- Numeric typeboolean- True/falsearray- List/collectiondictionary- Key-value pairs
- Write
.cherrifile - Compile with skip-sign:
./cherri file.cherri --skip-sign - Check for errors in output
- Fix any issues and repeat
- Test the unsigned
.shortcutfile locally
- Ensure code compiles without errors
- Compile with signing:
./cherri file.cherri - Wait for signing process (macOS or HubSign)
- Distribute the signed
.shortcutfile
alert("Hello World", "Greeting")
@name = askText("What's your name?")
alert("Hello, {name}!", "Personalized Greeting")
repeat 3 {
alert("Count: {RepeatIndex}", "Loop Demo")
}
menu "Pick a color:" {
item "Red":
alert("You chose red!")
item "Blue":
alert("You chose blue!")
}
This guide should help any LLM understand and write Cherri code effectively. Always refer to test files and action definitions for the most accurate syntax.