This appendix compresses the entire language into tables and one grammar. Nothing here is new; everything here is complete.
The grammar
program = { rule | function | statement } ;
rule = "when" event-phrase NEWLINE INDENT block DEDENT ;
function = "to" name-phrase NEWLINE INDENT block DEDENT ;
block = { statement } ;
statement = action { "and" action }
| "if" condition ["then"] block ["otherwise" block]
| "repeat" NUMBER "times" block
| ["repeat"] "for each" NAME "in" expr block
| ["repeat"] "while" condition block ;
action = built-in-action | name-phrase (* a function call *) ;
expr = sum { "," sum } (* comma builds a list *) ;
sum = prod { ("+"|"-") prod } ;
prod = value { ("*"|"/") value } ;
value = STRING | NUMBER | "true" | "false" | FIELD ;
condition = see the conditions table ;Lexical rules: indentation defines blocks (two spaces per level; a tab counts as two spaces); one statement per line; # begins a comment outside strings; strings take "…" or '…' with backslash escapes and {field} interpolation; operators require surrounding spaces; keywords are case-insensitive; top-level items (when rules, to definitions) may appear in any order; a file of bare statements runs in script mode.
Events
| Phrase (examples) | Key | Demo fields in the simulator |
|---|
| a new lead arrives / a lead is created | lead.created | name, phone, email, source, budget |
| a form is submitted | form.submitted | form, name, email, message |
| a message arrives | message.received | from, name, channel, text |
| an invoice is paid | invoice.paid | number, amount, name |
| a deal is won | deal.won | name, amount, owner |
when "custom.key" happens | as quoted | none (supply with --data) |
Actions
| Action | Form | Notes |
|---|
| score | score it with ai | sets score (0–100) and heat (hot/warm/cold) |
| assign | assign [it] to "Name" | routes the event's subject |
| reply | reply on <channel> "…" | message inline or as quoted line(s) indented beneath |
| send | send <channel> [to "addr"] "…" | channels: whatsapp, email, sms, instagram, webchat, slack |
| tag | add tag "label" | tags accumulate |
| task | create task "title" [for "Name"] | title interpolates |
| wait | wait N second(s)/minute(s)/hour(s)/day(s) | simulated locally; real delay in production |
| set | set name to expr | creates or replaces a variable |
| add | add expr to name | list → push; number → add; string → append; unset → set |
| incr | increase/decrease name by expr | unset name counts as 0 |
| log | log "…" / say "…" | trace note; no external effect anywhere |
| stop | stop | halts the run immediately |
Conditions
| Form | Meaning |
|---|
x is v / x is not v | equality / inequality (string-compared for words) |
x is above N (over, greater than, more than) | numeric > |
x is below N (under, less than) | numeric < |
x is at least N | numeric >= |
x contains "t" | substring, case-insensitive |
x | truthy: set, non-zero, non-empty, not false |
score is hot/warm/cold | heat band; requires prior scoring (hot >= 75, warm >= 45) |
Conditions are atomic — no and/or inside one. Compose with nested if (conjunction) or sequential ifs (disjunction).
Data types
| Type | Literals | Operations |
|---|
| number | 42, 3.5, -1 | + - * /, schoolbook precedence, left-assoc |
| string | "hi", 'hi' | + joins (either side); {name} interpolates |
| boolean | true, false | conditions; bare-name truthiness |
| list | v1, v2, v3 | for each … in; add … to pushes |
Coercion: + with a string joins as text; other arithmetic requires numbers and errors otherwise. An unset name used as a value is the name itself as a word.
Limits and guarantees
| Limit | Value | On breach |
|---|
while iterations | 1,000 | error naming the loop |
| function call depth | 16 | error naming the function |
| trace display | 400 lines | display truncates; execution continues |
| network / filesystem / imports | none exist | not expressible in the language |
The CLI
| Command | Purpose |
|---|
skript run f.skript [--event k] [--data json] [--score n] [--json] | execute against a simulated event |
skript check f.skript | parse only; line-numbered errors; exit 1 on failure |
skript new [name] | scaffold a starter file |
skript add <name> | install a marketplace package into the current directory |
skript install-editor | highlighting + snippets for VS Code-family editors |
skript version / skript help | the obvious |
skode is an alias for skript. Install: curl -fsSL https://developer.skode.ai/skript/install.sh | bash (Node >= 18).