Execute shell commands or code. Language specifier determines execution context. **Decision tree:** - Single line + pipes only → `cmd { ... }` (safe, recommended) - Needs `&&`, `||`, control flow → `sh { ... }` (full shell) - JavaScript/Python code → `js { ... }` / `python { ... }` ```mlld >> cmd (pipes only, safe) run cmd {echo Hello | tr '[:lower:]' '[:upper:]'} var @date = cmd {date} >> sh (full shell scripts) run sh { npm test && npm run build || echo "Build failed" } >> js/python (code execution) run js {console.log("hello")} var @result = js {return 42} ``` **Working directory override:** ```mlld run cmd:/ {pwd} >> runs in / run sh:/tmp {pwd} >> runs in /tmp run js:/tmp {console.log(process.cwd())} ``` **Stdin support:** ```mlld var @data = '[{"name":"Alice"}]' run cmd { cat | jq '.[]' } with { stdin: @data } >> Pipe sugar (equivalent) run @data | { cat | jq '.[]' } ``` **Parameter syntax by language:** - `cmd`: interpolate with `@param` - `sh`: use shell variables as `$param` - `js/python`: parameters passed as variables Define reusable commands, code, templates, or multi-statement blocks. **Simple forms:** ```mlld >> Command exe @list(dir) = cmd {ls -la @dir | head -5} >> JavaScript exe @add(a, b) = js { return a + b } >> Template exe @greet(name) = `Hello @name!` >> External template file exe @welcome(name, role) = template "./prompts/welcome.att" >> Prose (requires config) exe @analyze(data) = prose:@config { session "Analyze @data" } ``` **Prose execution** (LLM skill invocation): Prose requires a config reference specifying the model and skill: ```mlld var @config = { model: "claude-3", skillName: "prose" } >> Inline (interpolates like templates) exe @summarize(text) = prose:@config { summarize @text } >> File reference (.prose files do NOT interpolate) exe @review(code) = prose:@config "./review.prose" >> Template files (.prose.att or .prose.mtt interpolate) exe @greet(name) = prose:@config "./greet.prose.att" ``` Interpolation rules: - `prose:@config { inline }` - interpolates `@var` like templates - `"file.prose"` - no interpolation, raw content - `"file.prose.att"` - ATT interpolation (`@var`) - `"file.prose.mtt"` - MTT interpolation (`{{var}}`) Default skill is `"prose"` (OpenProse). Custom interpreters via `skillName`. **Block syntax** (multi-statement bodies): ```mlld exe @process(data) = [ let @validated = @validate(@data) let @transformed = @transform(@validated) => @transformed ] >> With accumulation exe @countItems(items) = [ let @count = 0 for @item in @items [ let @count += 1 ] => @count ] ``` Block rules: - Use `[...]` for multi-statement bodies - `let @var = value` for block-scoped variables - `let @var += value` for accumulation (arrays/strings/objects) - `=> value` required as last statement for return **When-first in exe** (value-returning): ```mlld exe @classify(score) = when first [ @score >= 90 => "A" @score >= 80 => "B" @score >= 70 => "C" * => "F" ] >> With blocks for side effects exe @handler(input) = when first [ @input.valid => [ show "Processing..." let @result = @transform(@input) => @result ] * => { error: "Invalid input" } ] ``` **Shadow environments** (expose JS helpers): ```mlld exe @double(n) = js { return n * 2 } exe @cap(s) = js { return s[0].toUpperCase() + s.slice(1) } exe js = { double, cap } >> expose to all js blocks var @out = js { cap("hello") + ": " + double(5) } >> "Hello: 10" ``` Write data to files or streams. ```mlld output @content to "out.txt" output @data to "config.json" output @message to stdout output @error to stderr output @config to "settings.yaml" as yaml ``` Syntactic sugar for `output to stdout`. Works in action contexts. ```mlld log @message >> same as output @message to stdout log `Processing: @item` >> In action contexts for @item in @items => log @item when @debug => log "Debug info" ``` Append newline-delimited records. ```mlld append @record to "events.jsonl" >> JSON object per line append "raw line" to "events.log" >> In pipelines var @_ = @data | append "audit.jsonl" >> In loops for @name in @runs => append @name to "pipeline.log" ``` `.jsonl` enforces JSON serialization. Other extensions write text. `.json` blocked. Stream output during execution. ```mlld stream @claude("prompt") >> keyword form stream @generateReport() >> directive form >> Parallel streams stream @a() || stream @b() >> concurrent, buffered results ``` Suppress: `--no-stream` flag or `MLLD_NO_STREAM=true`