DOC_INDEX
THEME
DOCS/Getting Started/CLI Reference

CLI Reference

Every orchstep command, its flags, and a verified example for each.

OrchStep is a single binary. Everything runs through one command:

orchstep [command] [flags]

Run orchstep [command] --help at any time for the authoritative, version-matched help. This page is the same surface, with a runnable example and real output for each command.

Command overview

CommandWhat it does
runExecute a task from a workflow
list-tasksPrint the callable (non-internal) task names
menuInteractive task picker (TUI)
serveLocal web dashboard (run tasks, live logs, history)
evalEvaluate a template/JS expression against the variable context
validateStatically check that a task's {{ vars.X }} resolve under each environment
lintCheck a workflow for anti-patterns
initScaffold a starter orchstep.yml
moduleManage modules (resolve, lock, verify, cache)
contextInspect captured execution data
versionShow the installed version

Global flags

These apply to every command:

FlagDescription
--log-level <level>silent, error, warn, info, debug, trace
-v, --verboseVerbose output
--config <file>Config file (default orchstep_config.yml)
-h, --helpHelp for the command

run

Execute a task. With no task name, the main task runs (or your top-level steps:). With no --file, OrchStep uses orchstep.yml in the current directory.

orchstep run [task] [flags]
FlagDescription
-f, --file <file>Workflow file to execute (default orchstep.yml)
--env <name>Environment to use (dev, staging, production, ...)
--var key=valueSet a runtime variable (repeatable)
--vars-file <file>Load variables from a YAML file
--dry-runShow what would execute without running anything
--openWith --dry-run: write the visual plan and open it in the browser
--output <fmt>pretty, plain, json (auto-detects TTY). With --dry-run: text, json, html
--json-file <file>Also write the structured run result (JSON) to this file
--stdin-var <name>Inject piped stdin as a named variable
--ignore-version-checkRun even if the workflow requires a different engine version
--break-before <step>Pause before the named step and open the inspector (repeatable). See Interactive breakpoints

Examples:

orchstep run                                   # run "main" from orchstep.yml
orchstep run deploy                            # run the "deploy" task
orchstep run -f release.yml publish            # a different workflow file
orchstep run deploy --env production --var replicas=10
orchstep run deploy --env staging --vars-file overrides.yml
orchstep run report --output json --json-file result.json
echo '{"env":"prod"}' | orchstep run deploy    # pipe JSON onto stdin
curl -s api/health | orchstep run check --stdin-var resp

Running a task prints each step, its command, and a status marker:

Workflow: my-service
Task: build
  Step: compile
  $ echo "go build -o bin/my-service ./cmd/..."
go build -o bin/my-service ./cmd/...
  [ok] compile
Result: success

Exit codes: 0 success, 1 runtime failure (also bad flags), 2 usage error (no subcommand in a non-TTY pipeline), 3 load/validation error, 4 failed assert. See Output & Exit Codes for the full table and the --output json shape.

Interactive breakpoints

Stop mid-run to inspect live state — the gap eval --explain (before a run) and context inspect (after) don't cover.

orchstep breakpoint: pausing before a step to inspect live outputs and variables, then continuing

Two ways to set one:

  • --break-before <step> (repeatable) — ad-hoc, no file edit. A bare name matches any step so named; a task.step name targets one task's step (handy when two tasks share a step name):
    orchstep run deploy --break-before ship              # any step named "ship"
    orchstep run deploy --break-before deploy.ship       # only deploy's "ship"
  • the breakpoint flag on a step — a declarative marker in the workflow:
    - name: ship
      func: shell
      flags: [breakpoint]     # pause right before this step runs
      do: "deploy {{ steps.build.image }}"

Either one pauses right before that step runs, after the step's own vars: / env: / dotenv: are applied, and opens a read-only inspector:

⏸  BREAKPOINT before step 'ship'
   [c]ontinue  [a]bort  [v]ars  [e]nv  [o]utputs  [h]elp   |   or type an expression to evaluate
break> o            # outputs of steps run so far
break> vars.region  # evaluate against live state
break> c            # resume   (a = abort)

The inspector is read-only (it never changes state, preserving capture/replay determinism) and secret values are masked. It is a no-op in a non-TTY context (CI, pipelines), during --dry-run, or when ORCHSTEP_SKIP_BREAKPOINT is set — so breakpoints never hang an unattended run.

breakpoint is a step flag alongside the logging flags (log_result, log_outputs, log_context) — see Step Flags.

Preview without running: --dry-run

--dry-run resolves variables, conditions, task calls and modules, then prints the plan - nothing executes:

orchstep run --dry-run
DRY RUN  workflow=my-service  task=main
         Build, test, and deploy my-service

STEPS
   1. build_stage  [task call]  executes
        calls: build
           1. compile  [shell]  executes
                | echo "go build -o bin/my-service ./cmd/..."
   2. test_stage  [task call]  executes
        calls: test
           1. unit  [shell]  executes
                | echo "unit tests passed (42/42)"
   3. deploy_stage  [task call]  executes
        calls: deploy
           1. smoke  [shell]  executes
                | echo "GET /health -> 200"

SUMMARY  6 steps, 6 execute
No steps were executed.

Add --open (or --output html) to get the interactive visual plan. See Previewing with Dry Run.


list-tasks

Print the callable task names, one per line (internal _-prefixed tasks are omitted). Script-friendly; pairs well with the tasks/ directory.

orchstep list-tasks [file]
orchstep list-tasks
build
db-migrate
deploy
main (default)
test

Launch the interactive task picker (TUI). Press a task's hotkey to run it; / enters fuzzy search; f cycles filters (all / a-z / public / internal); q quits. In a non-TTY context (CI, a pipe) it exits with a clear error instead of hanging.

orchstep menu [flags]

Accepts --file, --env, --var, and --vars-file (same meaning as run).

orchstep menu                       # pick a task from orchstep.yml
orchstep menu --file release.yml    # pick from a different workflow

serve

Start a local-first web dashboard (HTTP + SSE) for the workflow: run tasks on click, watch live logs and a live step-flow graph, and browse run history. The whole UI is embedded in the binary and runs offline; history is a single SQLite file. Binds 127.0.0.1 by default. Full walkthrough: The Web Dashboard.

orchstep serve [flags]
FlagDefaultDescription
--port7777Bind port
--host127.0.0.1Bind host (use 0.0.0.0 with --token for LAN sharing)
--token(none)Shared token required on every request (opt-in auth)
-f, --fileorchstep.ymlWorkflow file to serve
--db.orchstep/serve.dbSQLite store path for run history
orchstep serve                                   # http://127.0.0.1:7777
orchstep serve --port 8000                        # custom port
orchstep serve --host 0.0.0.0 --token "$(openssl rand -hex 16)"  # share on a trusted network

eval

Evaluate an expression exactly the way workflow conditions do - against the same merged variable context a run would have, without executing any steps. Great for debugging a condition. Input fully wrapped in {{ }} evaluates as a Go template; anything else as JavaScript (override with --lang).

orchstep eval [expression] [flags]
FlagDescription
-f, --file <file>Workflow file providing the variable context
--env <name>Environment to use
--var key=valueSet a variable (repeatable)
--vars-file <file>Load variables from a YAML file
--lang <lang>auto (default), template, or js
-q, --quietPrint only the value (no language/truthy annotation)
--explainShow effective variables with the precedence layer that won (provenance); pass a key to drill into one

Examples:

orchstep eval '{{ add 2 3 }}'                  # Go template -> 5
orchstep eval '2 + 3 > 4'                      # JavaScript  -> true
orchstep eval 'vars.replicas > 4'
orchstep eval --env production --var replicas=99 '{{ vars.replicas }}'
orchstep eval                                  # interactive REPL (:vars, :tpl, :js, :q)

Variable provenance

eval answers "what is the value"; --explain answers "why is it that value — which precedence layer won." With no key it prints every effective variable and its winning layer (like git config --show-origin); the (over ...) column shows which lower-precedence layers it shadowed.

$ orchstep eval --explain --env production --var replicas=9
VARIABLE  SOURCE       VALUE
db_host   environment  prod-db     (over defaults)
region    environment  eu-west-1   (over defaults)
replicas  runtime      9           (over defaults)

Pass a key (a bare name or vars.X) to see the full layer-by-layer breakdown, with * marking the winner:

$ orchstep eval --explain --env production region
region = eu-west-1   (from environment)
precedence (low -> high; last wins):
   defaults     us-east-1
 * environment  eu-west-1

Precedence order (low to high): defaults < group < environment < module < task < step < runtime.

It also reports the OS environment variables the workflow's top-level env: sets (values masked; {{ secrets.X }} shown as a placeholder — secrets are never resolved here), flagging when one overrides an inherited OS variable:

# OS environment set by the workflow's env: (masked; task/step env: not shown)
ENV VAR     SOURCE         VALUE
API_TOKEN   workflow env:  ***
AWS_REGION  workflow env:  us-east-1
HOME        workflow env:  /custom/home   (over inherited (os))

A key that names an env var drills into it the same way. Task/step-level env: and dotenv-vs-OS attribution aren't shown (they need a task/step context).

See Expression Playground for a live, in-browser version.


validate

Statically check a task's variable references without running it. validate scans every {{ vars.X }} a task uses and reports which would be unresolved - supplied by no layer in the merge chain (defaults -> group -> environment -> task/step vars: -> --var; see Environments for how the layers stack) - for a given environment. An unresolved reference renders to an empty <no value> at run time; this catches that before you ship.

orchstep validate [task] [flags]
FlagDescription
-f, --file <file>Workflow file (default orchstep.yml)
--env <name>Validate ONE environment in detail (per-step report)
--all-tasksValidate every non-internal task
--var key=valueTreat a runtime variable as supplied (repeatable)
--vars-file <file>Load runtime variables from a YAML file
--jsonStructured JSON output (for tooling / CI)
--strictExit 1 if any referenced variable is supplied by no environment

The example used below

The examples on this page run against this workflow (external env_config style). The deploy task references three variables; the environment files supply them at different layers:

# orchstep.yml
env_config: { env_dir: environments }
tasks:
  deploy:
    steps:
      - { name: build, func: shell, do: 'echo "building {{ vars.version }}"' }
      - { name: ship,  func: shell, do: 'echo "deploy {{ vars.version }} to {{ vars.target }} ({{ vars.monitoring }} monitoring)"' }
environments/
  defaults.yml          version: "2.4.0"      # baseline for every environment
  nonprod.yml           monitoring: basic      # GROUP layer — shared, no target
  nonprod-dev.yml       target: dev-cluster    # concrete environment
  prod.yml              monitoring: full       # GROUP layer — shared, no target
  prod-production.yml   target: prod-cluster   # concrete environment

So version comes from defaults.yml (present everywhere), monitoring from each group file, and target only from the concrete *-dev / *-production files - never from the nonprod / prod group layers. validate makes that visible:

The coverage matrix (default)

With no --env, validate prints an environment x variable matrix: which environment supplies each referenced variable, which environments are complete, and which variables are referenced but supplied nowhere (a likely typo or a forgotten declaration).

$ orchstep validate deploy
validate · workflow "shop" · task "deploy"

referenced variables (3): monitoring  target  version

coverage matrix (✓ supplied · absent):

  variable    (none)  nonprod  nonprod-dev  prod  prod-production
  monitoring
  target
  version

findings:
 nonprod         : 1 unresolved (target)
 prod            : 1 unresolved (target)

3 complete environment(s): nonprod-dev, prod-production

The (none) column is the baseline a run with no --env would see. A group layer like nonprod showing for target just means that group is a shared layer that doesn't itself set every value - which is fine when you deploy the concrete nonprod-dev, and worth knowing before you try to deploy nonprod directly. (If your group file does supply everything - e.g. one shared config applied to many instances - it shows complete, and is a perfectly valid target.)

Focused mode (--env)

Pass --env for a per-step report of one environment:

$ orchstep validate deploy --env nonprod
validate · task "deploy" · env "nonprod"

 deploy.build   version
 deploy.ship    target⚠

 1 unresolved under "nonprod": target
 pick a complete environment or pass the missing vars with --var.

In CI

--strict makes validate a gate: it exits non-zero when a referenced variable is supplied by no environment at all (the typo/forgotten-declaration case).

orchstep validate deploy --strict        # fail the build on a never-supplied var
orchstep validate deploy --env prod --strict --var build_id=$CI_SHA

Limits: references guarded by | default are never reported missing; dynamic accesses (index .vars, vars[expr]) are reported as unverifiable rather than guessed; v1 scans the task's own steps and does not descend into called tasks/modules.


lint

Check a workflow file for common anti-patterns and get suggestions.

orchstep lint [file]
orchstep lint
No issues found in orchstep.yml

init

Scaffold a complete, runnable starter orchstep.yml with explanatory comments.

orchstep init [flags]
FlagDescription
-t, --template <name>minimal (default), env, or ci
-f, --file <name>Output file name (default orchstep.yml)
--listList available templates
--forceOverwrite an existing file
orchstep init --list
Available templates:
  minimal  Hello-world starter with a verified assert (default)
  env      Environment-aware workflow (env_groups + environments, run with --env)
  ci       Build/test/package pipeline passing outputs between steps
orchstep init                     # minimal starter as orchstep.yml
orchstep init -t ci -f build.yml  # CI starter under a custom name

module

Manage remote and local modules. Subcommands:

SubcommandWhat it does
resolveResolve a module version from remote tags
lockGenerate or update orchstep.lock
updateRefresh orchstep.lock to the newest allowed versions
verifyVerify modules match their pinned commit + hash (CI gate)
infoShow information about a remote module
cacheManage the local module cache
orchstep module lock        # pin module versions into orchstep.lock
orchstep module verify      # fail if anything drifted from the lock (use in CI)

Full walkthrough: Lockfile & Supply Chain and Registry & Scopes.


context

Inspect captured execution data (when context collection is enabled).

SubcommandWhat it does
inspectLaunch the interactive context inspector (TUI)
reportGenerate execution reports
cleanClean up old context data
orchstep context inspect    # browse the last run's variables, outputs, logs

version

Show the installed version.

orchstep version
OrchStep v0.11.0
Workflow execution engine with contextual data management

Tips

  • Discover anything inline: orchstep <command> --help prints version-matched flags and examples - this page mirrors that output.
  • Shell completion: orchstep completion bash|zsh|fish|powershell generates a completion script for your shell.
  • Quieter or louder: --log-level silent for scripts; --log-level debug (or -v) when something misbehaves.

Where to go next