Runfile syntax

A Runfile is a catalog of callable functions. run looks for Runfile in the working directory (or parent directories) and injects its functions into an execution scope.

Function forms

  • Inline: concise single-line commands
    dev() cargo run
    fmt() cargo fmt
    
  • Block: multi-line bodies without trailing backslashes
    ci() {
        echo "Running CI..."
        cargo fmt -- --check
        cargo clippy
        cargo test
    }
    
  • function keyword: optional; both build() and function build() are accepted.

Signatures

Declare parameters in the function header. They become shell variables during execution.

# @desc Deploy to an environment
deploy(env: str, version = "latest") {
    echo "Deploying $version to $env"
}
  • Parameters are positional; the order in the signature matches CLI arguments.
  • Defaults make parameters optional.
  • A rest parameter captures the remaining arguments:
    echo_all(...args) echo "Args: $args"
    
    • When forwarding ...args, use cmd $args to expand into separate tokens; cmd "$args" collapses them into a single argument. If you need to preserve the original token boundaries (including spaces) safely, prefer cmd "$@" instead—for example, cargo test --package run "$@".
  • Type annotations are optional: param: type. Supported types: str/string, int/integer, float/number, bool/boolean, object/obj/dict. Types drive MCP schema generation and, in polyglot functions, automatic value conversion.
  • You can still reference legacy positional tokens ($1, $2) alongside named params.
  • Named parameters work in polyglot functions too (Python, Node.js, Ruby). run auto-injects variables so you can use name directly instead of sys.argv[1]. See Polyglot commands.

See Arguments for mapping/defaults and Variables for scope and environment details.

Namespaces

Use colons to group related tasks. Invoke with spaces or colons.

docker:build() docker build -t app .
docker:logs(service = "app") docker compose logs -f $service

Run as run docker build or run docker:build.

Sourcing other files

The source directive merges functions from another file into the current Runfile:

source ./shared.run
source ~/.runfiles/helpers.run
  • Paths can be relative (resolved from the Runfile's directory), absolute, or use ~/ for the home directory.
  • Quoted paths are supported: source "path with spaces.run".
  • Sourced files can themselves contain source directives (circular references are detected and skipped).
  • If a sourced file doesn't exist, a warning is printed to stderr and execution continues.
  • Functions defined later in the file override those from sourced files, so you can import a base set and selectively replace individual commands.
  • source directives inside function bodies are passed through to the shell interpreter as normal shell source commands—only top-level directives are expanded by run.
# Import shared helpers, override one locally
source ./team-defaults.run

deploy() {
    echo "Custom deploy for this project"
}

Comments and attributes

Lines beginning with # can hold human comments or attributes (e.g., # @desc). Attributes adjust behavior and metadata; see Attributes and interpreters.