Skip to content

CLI Usage

The @duckflux/runner package ships a quack binary that lets you run, lint, and validate workflows from the command line.

Terminal window
quack <command> <workflow.yaml> [flags]

Auto-detects your package manager (apt, brew, bun, npm) and installs accordingly. Falls back to downloading a standalone binary.

Terminal window
curl -fsSL https://duckflux.github.io/apt-repo/install.sh | bash

CommandDescription
runExecute a workflow
lintValidate schema and detect common issues (no execution)
validateFull validation including input schema
serverStart the web server UI for visual workflow observation
versionPrint the CLI version

Executes a workflow from a YAML file and prints the result to stdout.

Terminal window
quack run <workflow.yaml> [flags]

run is the default command — if the first positional argument is a .yaml file and no subcommand is given, it is implied:

Terminal window
quack workflow.yaml # same as: quack run workflow.yaml
FlagShortTypeDefaultDescription
--input-istringInput as key=value. Repeatable. Values are JSON-parsed, falling back to strings.
--input-filestringPath to a JSON file containing workflow inputs.
--cwdstringWorking directory for exec participants. See Working directory.
--event-backendstringmemoryEvent hub backend: memory, nats, or redis.
--nats-urlstringNATS server URL. Required when --event-backend=nats.
--nats-streamstringduckflux-eventsJetStream stream name.
--redis-addrstringlocalhost:6379Redis server address (host:port).
--redis-dbstring0Redis database number.
--trace-dirstringDirectory to write execution trace files. One file per run, named <executionId>.<ext>.
--trace-formatstringjsonTrace output format: json, txt, or sqlite.
--verbose-vbooleanfalsePrint error stack traces to stderr.
--quietbooleanfalseSuppress stdout output.

Inputs are merged from multiple sources. Higher entries take priority:

  1. --input flags (highest)
  2. --input-file contents
  3. JSON piped via stdin (when no other input source is provided)

Values are JSON-parsed first, falling back to plain strings:

Terminal window
--input name=World # {name: "World"}
--input count=3 # {count: 3}
--input active=true # {active: true}
--input data='{"x":1}' # {data: {x: 1}}
--input items='[1,2,3]' # {items: [1, 2, 3]}
--input flag # {flag: true} (no "=" → boolean true)
  • string output → printed as-is (no trailing newline added)
  • Object/array output → printed as formatted JSON (2-space indent)
  • null / undefined output → nothing printed
CodeMeaning
0Workflow succeeded
1Execution error (file not found, parse error, unhandled exception)
2Workflow ran but returned success: false
Terminal window
# Basic execution
quack run workflow.yaml
# Pass inputs
quack run workflow.yaml --input name=World --input count=3
# Inputs from file
quack run workflow.yaml --input-file inputs.json
# Piped inputs
cat inputs.json | quack run workflow.yaml
# Custom working directory with verbose errors
quack run workflow.yaml --cwd /workspace --verbose
# NATS event backend
quack run workflow.yaml \
--event-backend=nats \
--nats-url=nats://localhost:4222
# Redis event backend
quack run workflow.yaml \
--event-backend=redis \
--redis-addr=localhost:6379
# Write a JSON trace for each run
quack run workflow.yaml --trace-dir ./traces
# Write a SQLite trace (all runs in separate DB files)
quack run workflow.yaml --trace-dir ./traces --trace-format sqlite

Use --trace-dir to capture a structured execution record for each run. See Execution tracing for full details.


Validates a workflow file without executing it. Checks schema correctness, semantic consistency, and common authoring issues.

Terminal window
quack lint <workflow.yaml>
  1. Schema validation — the file must conform to the duckflux JSON schema.
  2. Semantic validation — participant references, variable bindings, and imports are verified.
  3. Lint warnings (non-blocking) — the following patterns are flagged:
    • Loops without both until and max conditions (infinite-loop risk)
    • Parallel branches writing to the same context variable (race condition risk)
    • Inline participants without an as name (output unreachable by name)

If all checks pass, valid is printed to stdout. Errors and warnings go to stderr.

CodeMeaning
0Workflow is valid
1Validation failed or file could not be read
Terminal window
quack lint workflow.yaml
# CI-friendly: capture all output
quack lint workflow.yaml 2>&1
# Check exit code
if quack lint workflow.yaml; then
echo "Ready to run"
fi

Performs the same checks as lint, and additionally validates provided inputs against the workflow’s declared inputs schema.

Terminal window
quack validate <workflow.yaml> [flags]
FlagShortTypeDefaultDescription
--input-istringInput as key=value. Repeatable.
--input-filestringPath to a JSON file containing inputs.

stdin is also accepted (same rules as run).

  1. Schema validation
  2. Semantic validation
  3. Input schema validation — types, enum, min, max, pattern, format, and required fields are all checked against the values you provide.
CodeMeaning
0All validations passed
1Validation failed
Terminal window
# Validate structure only
quack validate workflow.yaml
# Validate structure + inputs
quack validate workflow.yaml --input name=World --input count=3
# Inputs from file
quack validate workflow.yaml --input-file test-inputs.json
# Piped inputs
echo '{"name":"World"}' | quack validate workflow.yaml

Starts the duckflux web server UI — a local dev tool for executing and observing workflows visually. See Web Server UI for a full feature walkthrough with screenshots.

Terminal window
quack server [flags]
FlagTypeDefaultDescription
--trace-dirstringRequired. Directory to watch for execution trace JSON files.
--workflow-dirstringcwdDirectory to scan for .yaml / .yml workflow files.
--portstring3000HTTP port for the web UI.

If @duckflux/server is not installed in the current project, the CLI prompts to install it automatically:

@duckflux/server is not installed. Install it now? [Y/n]

Answering Y runs bun add @duckflux/server -D (falling back to npm install if Bun is not available).

Terminal window
# Start with trace output directory
quack server --trace-dir ./traces
# Custom workflow directory and port
quack server --trace-dir ./traces --workflow-dir ./workflows --port 8080

Prints the CLI version to stdout.

Terminal window
quack version
# 0.7.0

Always exits with code 0.


The --event-backend flag (used with run) selects the pub/sub layer for emit and wait participants.

BackendFlag valueInfrastructureReplayCross-process
In-memorymemory (default)NoneYesNo
NATS JetStreamnatsNATS serverNoYes
Redis StreamsredisRedis serverYesYes

For detailed configuration of each backend see Event hub providers.


Unknown command — prints available commands and exits with code 1.

Missing file argument — prints the command’s usage string to stderr and exits with code 1.

Backend not installed — if @duckflux/hub-nats or @duckflux/hub-redis is missing, the CLI prints an installation hint and exits with code 1:

Error: NATS backend requires @duckflux/hub-nats — install it with: bun add @duckflux/hub-nats

--nats-url missing — required when --event-backend=nats; exits with code 1 if omitted.

--verbose / -v — appends the full stack trace to stderr for any error, regardless of command.