EONYX Headless Mode: Running the Agent Without the TUI
Besides the interactive TUI, EONYX can run headless — perform a task and exit. That is what you need for scripts, pipes and CI: predictable output, JSON events and meaningful exit codes.
1 Running it
EONYX runs without the TUI through a single run subcommand — with separated streams and saved sessions, so the conversation can be continued.
1.1 The run subcommand
eonyx run "describe what this repository does"
eonyx run -m deepseek-v4-pro --yolo "fix the failing test"The prompt comes from the arguments or from stdin. The argument wins: if it is given, stdin is not read — which is why, when piping, you do not duplicate the prompt as an argument:
eonyx run "explain the error in the log" # prompt from the argument
{ echo "explain the error:"; cat error.log; } | eonyx run # prompt from stdinFlags: -m/--model, -s/--session <id> (continue a specific session), -c/--continue (continue the most recent one), --yolo (drop the permission gate), --json (events as NDJSON), --system-prompt (replace the system prompt).
1.2 stdout versus stderr
In normal (text) mode the streams are separated — this makes the output convenient for pipes:
- stdout — only the final response text from the model (streamed).
- stderr — reasoning, tool activity (
→ name,← result) and the summary line\n[tokens: N in, M out] [session: <id>].
So you can safely redirect the result:
eonyx run "generate a README from the code" > README.draft.md1.3 Sessions
Headless runs are saved as sessions too, so the conversation can be continued:
eonyx run "start refactoring the parser" # creates a session
eonyx run -c "now add tests" # continues the most recent one
eonyx sessions # list: id, date, message count2 For CI and scripts
For automation EONYX gives you machine-readable output and meaningful exit codes.
2.1 –json mode
--json prints NDJSON (one JSON record per line) to stdout — convenient to parse in a pipeline:
eonyx run --json "fix the test" | jq -c 'select(.type=="tool_end")'Event types: text, reasoning, tool_start (name, input), tool_end (name, result, is_error) and the final result (text, input_tokens, output_tokens, cached_tokens, session).
2.2 Exit codes
For CI it matters to tell outcomes apart — EONYX returns meaningful codes:
| Code | Meaning |
|---|---|
| 0 | success |
| 1 | general error (config, provider, persistence) |
| 2 | usage error (invalid arguments) |
| 3 | API/model error during streaming |
| 4 | task finished, but a tool was blocked by the gate |
| 5 | hit the max_steps limit without a final answer |
| 130 | interrupted (Ctrl-C) |
eonyx run --yolo "run the linter and fix the findings" || echo "exit $?"4 means the agent wanted to perform an action but had no permission — add the tool to allowed_tools or run with --yolo. Code 5 means the task did not fit into max_steps; raise the limit in the config.2.3 A CI example
#!/usr/bin/env bash
set -euo pipefail
export DEEPSEEK_API_KEY="$CI_LLM_KEY"
eonyx run --yolo --json "run go test ./... and fix the failing tests" \
| tee agent.log \
| jq -r 'select(.type=="result") | .text'3 Summary
- Running it
eonyx run "…"— prompt from the arguments or stdin (pipe)- flags
-m,--yolo,--system-prompt
- Streams
- stdout — only the model’s final answer
- stderr — tool activity and token stats
--json- NDJSON events:
text/reasoning/tool_start/tool_end/result - convenient to parse with
jq
- NDJSON events:
- Exit codes
- distinguish success from an API error (3)
- permission block (4),
max_stepslimit (5)
- Sessions
- headless runs are saved
-ccontinues the most recent one,-s <id>a specific one