# Run Commands and Eval Lisp


kli has two tools for executing code in a session: `bash` runs a shell command in a child process, and `eval` evaluates Common Lisp forms inside the running kli image. The agent calls them while it works, and you can call either one directly with a slash command.

Both tools are gated behind capabilities. They run only when the session grants them: `bash` needs `process/exec` and `eval` needs `image/eval`. With the default settings (no `capabilities` key) every tool is allowed. See [Restrict Tools With Capabilities](/kli/guides/restrict-what-kli-can-do) to deny one.

## Run a shell command

Type `/bash` followed by the command:

```
/bash ls -la src
```

Everything after `/bash` is the command line, passed to `sh -c`. So pipes, redirects, globs, and `&&` work as written:

```
/bash grep -rn TODO src | head -20
```

The tool returns stdout on success. When the command exits non-zero, the result is marked an error and includes stderr. An empty result means the command produced no output and exited zero.

## Set the working directory or pass stdin

The agent can run a command in a specific directory or feed it input. These are tool parameters, not shell syntax, so the agent supplies them on the tool call rather than you typing them after `/bash`. The `bash` tool accepts:

| Parameter   | Required | Effect                                             |
|-------------|----------|----------------------------------------------------|
| `command`   | yes      | The command line to run.                           |
| `directory` | no       | Working directory for the child process.           |
| `input`     | no       | Text written to the command's stdin.               |
| `shell`     | no       | Shell to invoke. Defaults to `sh`.                 |

From the `/bash` slash command, only the command line is available; the rest take their defaults. To change the working directory yourself, `cd` inside the command itself.

## Evaluate Common Lisp

Type `/eval` followed by one or more forms:

```
/eval (+ 1 2 3)
```

The forms are read and evaluated in order. The result is whatever the forms printed, followed by the value of the last form. Several forms in one call run left to right:

```
/eval (defparameter *x* 10) (* *x* *x*)
```

Forms read and evaluate in the `CL-USER` package by default. The agent can target another package through the tool's `package` parameter; unqualified symbols then intern there. Values print under bounded printer control: `*print-length*` is 100, `*print-level*` is 20, and `*print-circle*` is on, so a long or circular value prints a bounded representation instead of running away.

The forms run in the same image kli runs in, so they reach live state and can inspect or change kli mid-session. For what that image is and why it matters, see [The Live Image](/kli/concepts/the-live-image).

## Stay inside the timeouts

Both tools time out at 30 seconds by default. The hard maximum is 300 seconds; a longer request is clamped to it. There is no way to extend a single call past 300 seconds.

When a `bash` command times out, kli kills its whole process group (SIGTERM, then SIGKILL) and returns the output captured so far, marked as a timeout error. When an `eval` form times out, kli interrupts the evaluating thread. An interrupted form can leave image state partially modified, since it stops wherever it was, so the result says so.

To run something longer than 300 seconds, start it in the background from a `bash` command and poll its progress with later commands, rather than waiting inside one call.

## Know the output cap

Each tool caps its captured output at 1 MiB (1,048,576 characters):

- `bash` caps stdout and stderr at 1 MiB **each**. Past the cap the stream is truncated and the result notes `[stdout truncated at ... characters]`.
- `eval` caps total output at 1 MiB across everything the forms print. The cap applies as output is written, so even a non-terminating printing loop stops adding to the result at the cap.

When you expect a large result, narrow it before it reaches the tool: pipe a `bash` command through `head`, `tail`, or `grep`, and have `eval` return a count or a slice rather than a whole collection.

## Commands bash refuses

The `bash` tool runs to completion and returns captured output; it has no terminal to drive. So it refuses commands whose first word is an interactive program and returns an error instead of hanging:

```
vi  vim  nvim  nano  emacs
less  more  man
top  htop  watch
ssh  mosh
tmux  screen
```

The check looks past leading variable assignments and wrappers (`env`, `command`, `exec`, `time`, `sudo`, `doas`) to find the real command, so `sudo vim file` is refused too. Reach for non-interactive equivalents: read a file with `cat` instead of `less`, search with `grep` instead of opening an editor, run a remote command through whatever your environment exposes rather than an interactive `ssh` session.
