# CLI

> Every elelem command and option, with examples for chat, one-shot questions, pipes, and file bundles.


```text
elelem [command] [options] [args]
```

| Command | What it does |
|---|---|
| `chat` | Interactive REPL. The default when no command is given. |
| `ask <prompt>` | One turn, then exit. Reads stdin if it is a pipe. |
| `files` | Prints files as an XML bundle for pasting into a prompt. |
| `help` | Prints the usage text. |

| Option | What it does |
|---|---|
| `-p`, `--provider NAME` | Provider to use. Default: `stub`. See [Providers](/docs/providers/). |
| `--model NAME` | Model to use, passed to the provider as `model:`. Providers that do not read it ignore it. |
| `--system-prompt TEXT` | Role text placed before the system prompt. See [Context](/docs/context/). |
| `-h`, `--help` | Prints the usage text and exits. |

Options can go before or after the command. Any other command prints `Unknown command: NAME` and exits with status 1.

`--model` and `--system-prompt` are new in 0.13.0.

## chat

```bash
elelem chat -p anthropic
elelem -p ollama --model gpt-oss:latest
elelem chat -p anthropic --system-prompt "You are reviewing a Rails app. Do not edit files."
```

Prints `elelem vVERSION`, then reads lines at a `> ` prompt. A line starting with `/` runs a [slash command](/docs/tools-and-commands/#slash-commands); any other non-empty line is a turn.

| Key | Effect |
|---|---|
| Enter | Send the line. |
| Tab | Complete a command name, a command argument, or a file name. |
| Ctrl-D | End of input. The REPL exits with status 0. |
| Ctrl-C | Exits the process with status 1, even mid-turn. |

If building the session fails, for example an unknown provider or a missing API key, elelem prints `elelem: <message>` and exits with status 1.

## ask

```bash
elelem ask -p anthropic "What does lib/elelem/agent.rb do?"
```

Runs one turn with the words after `ask` as the prompt, joined by spaces, then exits. With no prompt, it prints `Usage: elelem-chat ask <prompt>` and exits with status 1.

### Piping input

When stdin is a pipe, its content is appended to the prompt in a fenced block:

```bash
git diff --staged | elelem ask -p anthropic "Write a commit message for this diff."
```

The model receives:

````text
Write a commit message for this diff.

```
diff --git a/lib/elelem/cli.rb b/lib/elelem/cli.rb
...
```
````

Only a pipe counts. A redirect such as `< notes.txt` is not read; use `cat notes.txt | elelem ask ...` instead. You still need a prompt on the command line.

### Where output goes

When stdout is a terminal, progress and the reply stream to stdout as they happen: thinking, tool calls, and each reply.

When stdout is a pipe or a file, progress goes to stderr and only the final reply goes to stdout, after the turn ends. The reply is wrapped in a Markdown code fence:

With the `stub` provider and `elelem-builtins` installed:

```bash
elelem ask hello > answer.txt
```

````text
```
done.
```
````

If the final reply is empty, elelem prints `elelem: no reply` and exits with status 1.

### No prompting

`ask` uses an input that never prompts. Anything that would ask you a question gets no answer. With the confirmation hook from `elelem-tools`, that means every tool set to `ask` is allowed without asking. Run `ask` only where you would let the tools run unattended.

`ask` also ignores input and output factories from plugins. It always uses the core output.

## files

```bash
elelem files > repo.xml
git ls-files '*.rb' | elelem files
```

Reads a list of paths, one per line, from stdin if it is a pipe, or from `git ls-files` otherwise. Prints each file that exists:

```text
<documents>
<document index="1"><source>README.md</source><document_content><![CDATA[# My project
]]></document_content></document>
</documents>
```

`index` is the path's line number in the input, so skipped lines leave gaps. Blank lines and paths that are not files are skipped. File content is written as-is inside `CDATA`, without escaping. Options are accepted but unused.

Use it to hand a set of files to a model in one prompt:

```bash
git ls-files lib | elelem files | elelem ask -p anthropic "Where is the plugin load path defined?"
```

## help

```bash
elelem help
```

Prints the same text as `elelem --help`:

```text
Usage: elelem [command] [options] [args]

Commands:
  chat              Interactive REPL (default)
  ask <prompt>      One-shot query (reads stdin if piped)
  files             Output files as XML (no options)
  help              Show this help

Options:
    -p, --provider NAME              Provider to use (default: stub)
        --model NAME                 Model to use, passed to the provider
        --system-prompt TEXT         Role text prepended to the system prompt
    -h, --help                       Show this help
```

## Other executables

Several plugin gems ship the same CLI under another name with a different default provider:

| Executable | Gem | Default `-p` |
|---|---|---|
| `elelem-anthropic` | `elelem-anthropic` | `anthropic` |
| `elelem-openai` | `elelem-openai` | `openai` |
| `elelem-ollama` | `elelem-ollama` | `ollama` |
| `elelem-llama` | `elelem-llama` | `llama` |
| `elelem-ggml` | `elelem-ggml` | `ggml` |
| `elelem-candle` | `elelem-candle` | `candle` |
| `elelem-llama2` | `elelem-llama2` | `llama2` |
| `elelem-ratatui` | `elelem-ratatui` | `stub` |

Commands and options are the same. Unlike `elelem`, the provider executables do not load `elelem-builtins`, so they start with no tools or commands unless a plugin file adds them. `elelem-ratatui` does load `elelem-builtins`.

`elelem-server`, `elelem-evals`, and `elelem-skills` have their own options. See their pages under [Plugins](/plugins/).

## Logging

elelem logs to stderr at the level in `ELELEM_LOG_LEVEL`, `warn` by default. Set it to `debug` to see every tool call and result:

```bash
ELELEM_LOG_LEVEL=debug elelem ask -p anthropic "List the files in lib."
```


Canonical: https://elelem.sh/docs/cli/

