Skip to content

Run from CI or scripts

Run Empryo without the UI in scripts and CI: pipe in a prompt, get JSON or live events, resume sessions, and fail a pipeline on a review verdict.

Recipes4 minutes to read
Copy & share
On this page10 sections

Headless mode runs the same agent with the same tools, but without the interface. Use it in shell scripts, git hooks, and CI pipelines.

Run a promptLink to this section

bash
# Prompt as an argument
empryo --headless "explain the auth middleware"

# Prompt from stdin
echo "find unused exports" | empryo --headless

# One JSON object with the result
empryo --headless --json "list all TODOs"

# One JSON event per line, while the run happens
empryo --headless --events "refactor the store"

The agent's answer goes to stdout. Progress lines go to stderr, so you can pipe the answer without extra noise.

Useful flagsLink to this section

FlagWhat it does
--model <id>Use a different model for this run
--mode autoLet the agent run commands and edits that would normally need your approval
--max-steps <n>Stop after this many steps
--timeout <ms>Stop after this many milliseconds
--system "..."Add your own instructions
--include <file>Add a file to the context. Repeatable.
--no-genomeSkip the startup code scan. Faster for quick questions.
--diffPrint the changed files at the end
--save-sessionSave the conversation so you can continue it later
--session <id>Continue a saved session
--chatMulti-turn chat over stdin
--review [what to check]Review the changes and exit with the verdict, instead of running a prompt. See review.
--quietHide the progress lines

See the CLI reference for every flag.

Approvals in headless modeLink to this section

Nobody is there to click "approve", so by default Empryo refuses anything that would normally ask you first, such as destructive commands or writes outside the project folder. The agent is told the action was denied and carries on without it.

If the job needs those actions, and you trust the environment it runs in, use --mode auto:

bash
empryo --headless --mode auto "update the lockfile and fix the build"

The `approvals` settings are for the desktop app and the terminal UI. A headless run doesn't read them. Reading a web page never asks there, but work outside the project, destructive commands and requests that send data are refused unless you use --mode auto.

Exit codesLink to this section

CodeMeaning
0Success, or a PASS review
1Error
2Timed out
3Review verdict: FAIL
4Review verdict: PARTIAL
5A computer-use step needs a person
130Stopped with Ctrl+C

Fail a pipeline on a reviewLink to this section

bash
# 0 = PASS or nothing changed, 3 = FAIL, 4 = PARTIAL
empryo --headless --review "check the migration for data loss" --quiet

A fresh agent reads the changed files. It has not seen the conversation that made them, so it judges the code on its own. If nothing changed, it exits 0 without calling a model.

CI exampleLink to this section

yaml
# .github/workflows/lint.yml
- name: Auto-fix lint
  env:
    ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
    EMPRYO_NO_PROMPT: "1"
  run: |
    empryo --headless --max-steps 30 --timeout 180000 --diff \
      "run the linter, fix every issue, then typecheck"

Continue a sessionLink to this section

bash
# Step 1: investigate and save
empryo --headless --save-session "analyze the auth module and list the issues"

# Copy the session id from the output, then:
empryo --headless --session <id> --save-session "now fix them"
empryo --headless --session <id> "write tests for the fixes"

Read the event streamLink to this section

bash
empryo --headless --events "refactor the store" | while read -r line; do
  type=$(echo "$line" | jq -r '.type')
  case "$type" in
    tool-call) echo "→ $(echo "$line" | jq -r '.tool')" ;;
    done)      echo "done in $(echo "$line" | jq -r '.duration')ms" ;;
  esac
done

The main event types are start, text, tool-call, tool-result, step, error, done, and session-saved. Longer runs can also send events for warnings, compaction, helper agents, and review verdicts, so ignore types you do not handle.

What is different from the interactive appLink to this section

  • No interface, editor panel, or splash screen.
  • Actions that need approval are refused unless you use --mode auto.
  • You cannot send messages to the agent during the run, except in --chat mode.

Tips for CILink to this section

  • Store API keys as CI secrets and pass them as environment variables.
  • Always set --max-steps and --timeout so a stuck run cannot use up your budget.
  • Set EMPRYO_NO_GENOME=1 to skip the code scan on small jobs.
  • Set EMPRYO_NO_PROMPT=1 so the first-run add-on prompt never waits for input.