Guides

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.

Beginner 10 minutes elelemelelem-builtinselelem-ollama

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 your first session.
  • A git repository to try it in.

1. Ask one question #

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:

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

The model receives:

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:

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

Drop stderr to see only the reply:

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):

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

4. Draft a commit message #

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:

elelem files | head -3
<documents>
<document index="1"><source>Gemfile</source><document_content><![CDATA[source "https://rubygems.org"
...

Pipe in a list of paths to choose the files:

git diff --name-only main | elelem files | elelem ask -p ollama "explain what this branch changes"
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:

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:

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 #