# Use elelem in shell pipelines

> Pipe text into elelem ask, feed it files with elelem files, and use the reply in scripts and git workflows.


At the end of this guide you will use elelem like any other Unix filter:
text in on stdin, a reply out on stdout, progress on stderr. You will
review a diff, draft a commit message, and ask questions about a whole
repository, each in one line.

## Before you start

- elelem and `elelem-builtins` installed, with a working provider. The
  examples use `-p ollama`; any provider works. See
  [the Quickstart](/docs/quickstart/).
- A git repository to try it in.

## 1. Ask one question

```bash
elelem ask -p ollama "what test framework does this project use?"
```

`ask` runs one turn and exits. The words after `ask` that are not options
are joined into the prompt. The agent still
has its tools: it can read files and run commands to find the answer.

## 2. Pipe text in

When stdin is a pipe, elelem appends it to your prompt inside a code
fence:

```bash
git diff --staged | elelem ask -p ollama "review this diff for bugs"
```

The model receives:

````text
review this diff for bugs

```
diff --git a/lib/app.rb b/lib/app.rb
...
```
````

> **Note:** elelem reads stdin only from a pipe. A redirect such as
> `elelem ask "summarize" < notes.txt` is ignored. Use
> `cat notes.txt | elelem ask -p ollama "summarize"`.

## 3. Separate the reply from the noise

When stdout is not a terminal, `ask` splits its output. Thinking, tool
calls, and a copy of the reply go to stderr. Only the final reply goes
to stdout, wrapped in a code fence:

````text
```
The diff looks correct. One issue: `parse` no longer handles nil.
```
````

Drop stderr to see only the reply:

```bash
git diff --staged | elelem ask -p ollama "review this diff for bugs" 2>/dev/null
```

To get the reply without the fence, remove the first line and the last
two (the closing fence and a blank line):

```bash
unfence() { sed '1d;$d' | sed '$d'; }
```

## 4. Draft a commit message

```bash
git diff --staged \
  | elelem ask -p ollama "write a commit message for this diff. reply with the message only, no fences." 2>/dev/null \
  | unfence > /tmp/msg
git commit -e -F /tmp/msg
```

`-e` opens the message in your editor before committing, so you read it
first.

> **Note:** `ask` has the same tools as `chat`, and `elelem-builtins`
> runs them without asking. A model told to "commit this" may run
> `git commit` itself. Ask for text when you want text.

## 5. Give it the whole repository

`elelem files` prints files as an XML document collection, a format models
read well. With no input, it uses `git ls-files`:

```bash
elelem files | head -3
```

```text
<documents>
<document index="1"><source>Gemfile</source><document_content><![CDATA[source "https://rubygems.org"
...
```

Pipe in a list of paths to choose the files:

```bash
git diff --name-only main | elelem files | elelem ask -p ollama "explain what this branch changes"
```

```bash
git ls-files 'lib/*.rb' | elelem files | elelem ask -p ollama "find methods that are never called"
```

The model gets every file's contents up front instead of reading them one
by one with tools. Keep the list within your model's context window.

## 6. Set a role

`--system-prompt` puts text in front of elelem's system prompt for one
run:

```bash
git diff --staged | elelem ask -p ollama --system-prompt "You are a security reviewer." "review this diff" 2>/dev/null
```

`--model` picks the model for one run, as in `chat`.

## 7. Check for failure in scripts

`ask` exits with status 1 and prints `elelem: ...` to stderr when it
cannot start, for example with an unknown provider, or when the reply is
empty (`elelem: no reply`).

An error from the model's API is different. elelem treats it as the
reply: it prints `Error: ...` and exits 0. Check for it:

```bash
reply=$(elelem ask -p ollama "summarize README.md" 2>/dev/null | unfence)
case "$reply" in
  Error:*) echo "$reply" >&2; exit 1 ;;
esac
echo "$reply"
```

## Running without a terminal

`ask` never prompts. It uses a null input, so it works under cron, in CI,
and in editor integrations. If you load `elelem-tools`, its `confirm`
plugin allows tools marked `ask` without prompting when there is no
terminal to ask on. Set rules you need enforced to `deny` in
`.agents/permissions.json`.

Set `ELELEM_LOG_LEVEL` (`debug`, `info`, `warn`, `error`) to control the
log on stderr. The default is `warn`.

## What you built

A set of one-liners: review a diff, draft a commit message, and ask about
any set of files, with clean output on stdout and a way to catch errors.

## Next steps

- [Run elelem fully offline](/guides/local-models/) so pipelines never
  leave your machine.
- [Write a tool plugin](/guides/write-a-tool/) for the steps your scripts
  repeat.
- Read the [elelem](/plugins/elelem/) page for every command and option.


Canonical: https://elelem.sh/guides/scripting/

