# Run kli Headless or Piped


You can drive kli without typing into a live terminal. Pipe a prompt in and kli runs one turn and prints the result. Redirect a file in and kli runs each line as its own turn. For longer-lived unattended work, you can also boot a profile that brings up kli without the terminal UI at all.

## Feed a prompt over a pipe

Run kli the same way you always do, but connect its standard input to something other than a terminal:

```sh
echo "summarize the changes in the last commit" | kli
```

kli starts in the default profile and brings up the agent, but instead of the interactive editor it detects that standard input is not a terminal and switches to a line loop. The line loop reads one line, submits it as a turn, waits for the agent to finish that turn, then reads the next line. When input reaches end of file, kli exits.

Run kli from inside a project directory so it reads and edits that project's files, exactly as in an interactive session.

## Feed many turns from a file

Because the line loop runs one turn per line, a file of prompts runs as a sequence of turns in one session, each turn seeing the results of the ones before it:

```sh
kli < turns.txt
```

Each line in `turns.txt` is submitted in order, and the session ends at end of file.

Keep one instruction per line. A blank line is submitted as an empty turn, so strip blank lines from the file if you do not want them.

## Resume a session in a piped run

A piped run starts a fresh session by default. To continue the most recently stored session instead, pass `--continue` (or `-c`):

```sh
echo "now run the test suite" | kli --continue
```

kli resumes the newest loadable stored session, then runs the piped line as the next turn in it. This lets a script pick up where an earlier interactive or piped run left off. See [Persist and Resume Sessions](/kli/guides/persist-and-resume-sessions) for how sessions are stored.

## Use kli inside a script

The piped form composes with the rest of your shell. Build the prompt from other commands and pipe it in:

```sh
git diff --staged | {
  echo "Write a one-paragraph commit message for this diff."
  cat
} | kli
```

kli's own output goes to standard output, so you can capture or pipe it onward. Errors and boot diagnostics go to standard error, so redirect each stream where you want it:

```sh
echo "list every TODO comment in src/" | kli > result.txt 2> kli.log
```

When stripping kli's reply down to a value a script can use, prefer prompts that ask for exactly the output you want and nothing else.

## Pick a boot profile

A profile is the set of extensions kli installs at boot. The default profile, `interactive-terminal`, is the one a normal interactive session uses, and it is also the one the piped line loop above runs under. kli selects a profile from, in order:

1. the `--profile NAME` flag,
2. the `KLI_PROFILE` environment variable,
3. the `profile` key in `settings.json`,
4. the default, `interactive-terminal`.

So a script can set the profile per invocation:

```sh
kli --profile headless
```

or for a block of commands at once:

```sh
export KLI_PROFILE=headless
```

For unattended runs, kli ships the `headless` and `autonomous` profiles, both of which boot without the terminal UI; the next two sections describe each. For the full roster and how to define your own, see [Switch and customize profiles](/kli/guides/switch-and-customize-profiles).

## Boot the headless profile

The `headless` profile installs kli's baseline extensions and nothing else: no terminal UI and no model providers. It boots the kernel, holds it alive, and does not enter an interactive loop or read prompts from standard input.

```sh
kli --profile headless
```

Use this profile to bring up kli as a long-running process you drive by other means rather than by typing or piping prompts. It is not the profile for running a one-shot prompt; for that, pipe into the default profile as shown above. Boot diagnostics that an interactive session would show in the transcript are printed to standard error instead.

## Boot the autonomous profile

The `autonomous` profile installs the baseline extensions and the model providers, then declares a set of extension points it expects you to fill: `planner`, `scheduler`, `watchdog`, and `recovery`. Like `headless`, it boots without the terminal UI.

```sh
kli --profile autonomous
```

The profile names those four points but does not provide them. It is a starting point for an unattended agent that you complete by installing extensions that supply a planner, a scheduler, a watchdog, and a recovery strategy. Without those, the profile boots the baseline agent and the providers but has no driver of its own. See [Install a Remote Extension](/kli/extend/sharing-extensions) for how extensions are added.

## Related

- [The Agent Loop](/kli/concepts/the-agent-loop) — what one turn does.
- [Connect a Provider](/kli/guides/connect-a-provider) — a model credential the default and autonomous profiles need.
- [Persist and Resume Sessions](/kli/guides/persist-and-resume-sessions) — how `--continue` finds a session.
- [Installation](/kli/cli/installation) — getting the `kli` binary onto the machine running your script.
