Your first run

This tutorial walks you through writing and running your first Jaiph program. By the end of it you will have written a single .jh file, run it with the jaiph CLI, watched the live progress tree, and looked at the run artifacts the runtime writes under .jaiph/runs/.

This tutorial uses only script steps, so you do not need an agent backend or API keys. The follow-up tutorial Your first agent run adds a prompt step on top of what you build here.

What you will build

You will write a file with one script step that prints a greeting, and a return that passes the script’s output back as the run’s return value. The whole file is five lines.

Prerequisites

Node and API keys are not required for this tutorial. jaiph run executes on the host.

1. Install the CLI

Install the standalone binary:

curl -fsSL https://jaiph.org/install | bash

The installer downloads a per-platform binary, verifies its signature and checksum, and writes it to ~/.local/bin/jaiph. See Install and switch versions for other options, such as JAIPH_BIN_DIR and version switching.

Confirm the install:

jaiph --version

If the command is not found, prepend the install directory to PATH:

export PATH="$HOME/.local/bin:$PATH"

2. Write the file

Create a fresh directory and write a file named hello.jh:

script greet = `echo "Hello, ${1:-world}!"`

export def main(who) {
  return run greet(who)
}

Here is what each line does:

3. Run it

jaiph run ./hello.jh "Adam"

Before any step runs, the CLI prepares the file in two steps:

You should see this (timings will differ):

Jaiph: Running hello.jh

def main (who="Adam")
  ▸ script greet (1="Adam")
  ✓ script greet (0s)

✓ PASS def main (0.2s)

Hello, Adam!

The first line is the run banner. The def main row and the indented and rows are the live progress tree. A marks a step that has started, a marks a step that has finished, and (0s) is the elapsed time for that step. The root row is static, and only nested steps print and lines. The Hello, Adam! line after PASS is the return value of export def main, which jaiph run prints on stdout after a successful run.

4. Inspect the run artifacts

Every run writes durable files under .jaiph/runs/<YYYY-MM-DD>/<HH-MM-SS>-<entry>/ in UTC. List the most recent run:

ls -la .jaiph/runs/*/*/

The layout you should see:

Read the captured script output and the return value:

cat .jaiph/runs/*/*/000002-script__greet.out
cat .jaiph/runs/*/*/return_value.txt

Both should match the line printed after PASS. The full artifact layout is documented in the durable artifact layout section of the architecture page. The event types in run_summary.jsonl are documented in the run artifacts section of the CLI reference.

Replace the script body with one that exits non-zero:

script greet = `echo "Hello, ${1:-world}!" && exit 7`

export def main(who) {
  return run greet(who)
}

Re-run with the same arguments:

jaiph run ./hello.jh "Adam"

The CLI prints a ✗ FAIL line on stderr, then a block with Logs:, Summary:, out:, and err: lines that point to the run directory, followed by an Output of failed step: excerpt. The process exits non-zero. return_value.txt is not written on failure, only on success.

Where to go next

Revert the failing script body so the run passes again, then pick a direction: