Plugins / Core
elelem-builtins
Read, write, run.
The default tools and slash commands: read and write files, run shell commands, and manage the session. Loaded automatically by the elelem command when installed.
gem install elelem-builtinselelem-builtins turns a bare elelem install into a working agent. It adds
3 tools (read, write, execute), 7 slash commands, and the terminal
output you see in elelem chat. execute gives the model a shell, so anything you can do from
bash, it can do.
Install #
gem install elelem elelem-builtinsThere is nothing to enable. The elelem executable requires
elelem/builtins on startup if the gem is installed.
Configure #
ELELEM_CMD_TIMEOUT sets a limit, in seconds, for each execute command.
When it expires, elelem sends TERM to the command’s process group, then
KILL half a second later, and appends
[command timed out after Ns] to the output. Without it, commands run
until they exit.
Two optional programs improve the output when they are on your PATH:
Without them, elelem prints plain text.
Use #
Tools #
| Tool | What it does | Params |
|---|---|---|
read | Returns the contents of a file. Aliases: open. | path (required) |
write | Writes a file, creating parent directories. Replaces the whole file. | path, content (both required) |
execute | Runs bash -c COMMAND in the current directory and returns the exit status and combined stdout and stderr. Aliases: bash, sh, exec. | command (required) |
Details that matter:
readon a missing path returns the errornot found.- Before
writereplaces an existing file, it prints a coloreddiff -uof the change, when stdin is a terminal. There is no prompt; the write happens either way. - After
write, if a tool namedverifyexists (it does whenelelem-toolsis loaded), elelem runs it on the written path. You see its output; the model does not get its result. executestreams output to the terminal as it arrives. Output longer than 10,000 characters is cut to the first and last 5,000, with a note saying how many characters were removed. A non-zero exit status is still a successful tool call; the model readsexit_statusto tell.
The aliases write<|channel|> and execute<|channel|> also exist. They
catch tool names some models emit with a stray chat-template token.
Slash commands #
| Command | What it does |
|---|---|
/help | Lists the slash commands. |
/exit | Exits elelem. |
/clear | Clears the conversation history. |
/context | Lists each message in the context with its role and the first 60 characters. |
/context N | Shows message N in full. |
/context json | Prints the full context, system prompt included, as JSON. |
/provider | Lists registered providers. |
/provider NAME | Switches to provider NAME for the rest of the session. The conversation is kept; --model is not passed to the new provider. |
/reload | Re-runs the plugin files in ~/.agents/plugins and .agents/plugins. See limitations. |
/tools | Prints a table of the available tools. |
/tools NAME | Prints one tool’s description, parameters, and aliases. |
/provider and /tools tab-complete their argument.
Example session #
elelem v0.13.0
> /tools
| Tool | Description |
|------|-------------|
| read | Read file |
| write | Write file |
| execute | Run shell command (supports pipes and redirections) |How it works #
Each tool and command is a separate setup block in its own file under
lib/elelem/builtins/, registered with Elelem.configure when the gem is
required. The gem also registers Elelem::Builtins::Terminal as the output
for interactive sessions. It prints a dot every 0.1 seconds while waiting
for the model, renders Markdown through glow, marks failed execute
calls with x, and copies everything it prints to a transcript file.
Transcripts are written to
$XDG_STATE_HOME/elelem/sessions/TIMESTAMP-PID.transcript, which is
~/.local/state/elelem/sessions/ by default. They are plain append-only
text, including terminal color codes. elelem does not read them back.
elelem ask does not use this output; it uses the core output, so no
transcript is written for one-shot queries.
Limitations #
- No permission checks.
executeruns whatever the model sends, andwriteoverwrites without asking. For prompts before a tool runs, addelelem-tools, which includes a permissions hook. writealways replaces the whole file. For targeted edits, theedittool is inelelem-tools./reloadclears every setup block before re-running plugin files. These setup blocks are registered once, when the gem is required, so after/reloadthe builtin tools and commands are gone,/reloadincluded. Restart elelem instead.- Transcripts are never cleaned up.
/clearempties the conversation but not the system prompt, which is rebuilt fromAGENTS.mdon every request anyway.
Development #
git clone https://git.mokhan.ca/elelem/builtins.git
cd builtins
bin/setup
bin/test
bin/lintThe specs cover the Markdown rendering behind /tools.
Environment #
| Variable | Default | Description |
|---|---|---|
ELELEM_CMD_TIMEOUT | none | Seconds before an execute command is killed. Unset or empty means no timeout. |
XDG_STATE_HOME | ~/.local/state | Base directory for session transcripts, written to elelem/sessions/ under it. |