Contents

EONYX Headless Mode: Running the Agent Without the TUI

EONYX also runs headless: it does the task and exits.
That is what scripts, pipes and CI need.
Predictable output, JSON events, meaningful exit codes.

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 never read.
So when you pipe, do not repeat 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 stdin

Flags: -m/--model, -s/--session <id>, -c/--continue, --yolo, --json, --system-prompt.

In text mode the streams are separated.
That makes the output easy to pipe.

  • stdout β€” only the model’s final answer, streamed.
  • stderr β€” reasoning, tool activity (β†’ name, ← result) and the summary line \n[tokens: N in, M out] [session: <id>].

So redirecting the result is safe:

eonyx run "generate a README from the code" > README.draft.md

Headless runs are saved too.
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 count

--json prints NDJSON to stdout, one JSON record per line.
Easy 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).
The final result carries text, input_tokens, output_tokens, cached_tokens and session.

CI has to tell outcomes apart.
So the codes mean something:

CodeMeaning
0success
1general error (config, provider, persistence)
2usage error (invalid arguments)
3API/model error during streaming
4task finished, but a tool was blocked by the gate
5hit the max_steps limit without a final answer
130interrupted (Ctrl-C)
eonyx run --yolo "run the linter and fix the findings" || echo "exit $?"
Codes 4 and 5 are not β€œjust an error”
Code 4 means the agent wanted to act and 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.
#!/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'
Cheat sheet
  • 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
  • Exit codes
    • distinguish success from an API error (3)
    • permission block (4), max_steps limit (5)
  • Sessions
    • headless runs are saved
    • -c continues the most recent one, -s <id> a specific one