output writes to files and stdout. log writes to stderr. append adds to existing files. stream enables real-time token-by-token output from LLM calls.

Output Directive

output @content to "out.txt"
output @data to "config.json"
output @message to stdout
output @error to stderr

Objects and arrays are automatically serialized to JSON when writing to .json files. For other file types, the value is converted to a string.

See Also

Log Directive

var @debugMode = true

log @message                        >> same as output @message to stderr
log `Processing: @item`

>> In action contexts
for @item in @items => log @item
when @debugMode => log "Debug info"

See Also

Append Directive

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.

Streaming

>> In definition (recommended)
exe @llm(prompt) = stream cmd {
  claude -p "@prompt" --output-format stream-json --verbose --include-partial-messages
} with { streamFormat: "claude-code" }

show @llm("Explain TCP/IP")           >> streams tokens as they arrive

>> At invocation
exe @raw(prompt) = cmd {claude -p "@prompt" --output-format stream-json --verbose --include-partial-messages}
run stream @raw("Hello") with { streamFormat: "claude-code" }

Definition-level stream and streamFormat are inherited by both run @exe() and show @exe().

import { @haiku } from @mlld/claude-stream
show @haiku("Explain TCP/IP")        >> streams + parses by default

Format Adapters

NDJSON streams require a format adapter to parse and display incrementally.

>> Built-in adapter (string shorthand)
run stream @exe("prompt") with { streamFormat: "claude-code" }

>> Installable adapter
import { @claudeAgentSdkAdapter } from @mlld/stream-claude-agent-sdk
run stream @exe("prompt") with { streamFormat: @claudeAgentSdkAdapter }
Adapter Aliases Parses
ndjson Generic NDJSON (default)
claude-code claude-agent-sdk Claude CLI stream-json events

Without an adapter, raw NDJSON passes through unformatted.

Shell Streaming

Non-NDJSON commands stream raw stdout:

exe @build() = stream sh {npm run build}
show @build()                          >> live build output

Parallel

stream @a() || stream @b()            >> concurrent, buffered per-task

Suppress

mlld script.mld --no-stream
MLLD_NO_STREAM=true mlld script.mld

Debug

mlld script.mld --show-json           >> mirror NDJSON to stderr
mlld script.mld --append-json out.jsonl  >> save events to file

Limitations

  • After-guards conflict with streaming (output must be complete for validation)
  • Pipeline stages buffer between stages; streaming is within each stage