1 wf cli
~larandar edited this page 2026-09-09 13:34:00 +02:00

← Home

wf-cli

The operator surface of the executor: the wf binary. The library (lib.rs) holds the workflow model, execution engine, and event emitter; main.rs is a thin wrapper over commands::dispatch, so integration tests exercise exactly the surface the binary uses.

Commands

wf run <workflow.yaml> [args...]   run a workflow (args reach steps as WF_ARGS, newline-joined)
wf check <workflow.yaml>           validate a workflow without running it
wf help                            show help

wf check runs the full executor-core pipeline — parse, normalize, bind — and stops there. wf run executes.

Exit codes — stable contract

Code Meaning
0 success
1 a step failed or timed out
2 usage error or invalid workflow (Parse/Validation)
3 gate rejected the run (Gate)
4 sandbox error (Sandbox)
5 harness error — step could not be executed (Harness)
6 i/o error (Io)

The mapping lives in exit_code(&WorkflowError): one error kind from executor-core, one code. The numbering is a published contract (wf help prints it); scripts may rely on it.

JSON event stream

wf run emits structured progress events as one self-contained JSON object per line on stdout — incrementally consumable with jq -c or a log shipper, and the same stream the integration tests parse. Diagnostics go to stderr, never mixed into the event stream.

Events observed on a run:

  • run_started — workflow name, step count
  • step_started — step name, tool
  • step_finished — step, exit code, handover bytes, duration, captured stdout
  • step_failed — step, exit code, duration, captured stdout

Step stdout echoed inside an event is clipped at 64 KiB; past that the stdout field is truncated and stdout_truncated is set — the full stream is never silently dropped.

Verification

The crate carries an integration suite that drives the same dispatch the binary uses and parses the emitted event lines, so the exit-code and event contracts are checked against the real surface, not a mock.