# Switch and Customize Profiles


A profile is the set of extensions kli installs at boot: which model providers load, whether the terminal UI comes up, which tools are present. kli ships these builtins:

- `interactive-terminal` — the default. Boots the terminal UI with all the model providers and the full tool set.
- `headless` — the baseline kernel and tools with no terminal UI and no provider extensions. Holds the process open for a programmatic driver.
- `human-in-loop` — the interactive profile, declaring an `approval` seam for an extension you supply.
- `autonomous` — providers and tools without the terminal UI, declaring `planner`, `scheduler`, `watchdog`, and `recovery` seams.

This guide shows how to choose one at startup, switch while kli runs, and define your own.

## Choose a profile at startup

Name a profile on the command line:

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

Or set it in the environment, which kli reads when `--profile` is absent:

```sh
export KLI_PROFILE=headless
kli
```

To make the choice stick without a flag or env var, set the `profile` key in `settings.json`:

```json
{
  "profile": "headless"
}
```

kli resolves the boot profile in this order, taking the first that names one:

1. `--profile <name>`
2. `KLI_PROFILE`
3. the `profile` key in `settings.json`
4. the default, `interactive-terminal`

Set it in `settings.json` (global `~/.config/kli/settings.json`, project `<repo>/.kli/settings.json`; project wins) — see [Settings](/kli/config/settings).

A name that resolves to nothing warns and boots the default profile instead. The warning lands in the transcript as a boot diagnostic.

## Switch profiles while kli runs

Run `/profile` with no argument to list every profile, builtins first, then the ones you defined. The active one carries a `*`:

```
Profiles:
* interactive-terminal
  headless
  human-in-loop
  autonomous
  review
```

Pass a name to switch:

```
/profile review
```

A live switch re-bases your own extensions onto the target profile: kli installs the ones the target enables that are not yet present, and retracts the ones present that the target disables. The reply names what changed:

```
Switched to review. Installed: my-linter.
```

The delta is computed against what is actually installed, so any manual `/enable` and `/disable` you ran since boot re-bases too.

Two switches do not apply:

- Naming the active profile reports that it is already active and changes nothing.
- A profile whose builtin base differs from the running one cannot apply live, because the base set installs only at boot. The builtins each have a distinct base, so a live switch between them always lands here. kli tells you to restart, for example `Restart with --profile autonomous`.

## Define your own profile

Add a `profiles` block to `settings.json`. Each key is a profile name; each value describes how it differs from a builtin:

```json
{
  "profiles": {
    "review": {
      "extends": "interactive-terminal",
      "enable": ["my-linter"],
      "disable": ["scratch-notes"],
      "settings": {
        "defaultProvider": "anthropic",
        "defaultModel": "claude-opus-4-6"
      }
    }
  }
}
```

The fields:

- `extends` — the profile this one builds on, a builtin or another profile you defined. Omit it and the profile builds on `interactive-terminal`. The chain must bottom out at a builtin; a cycle or a dangling target is reported and the profile is skipped.
- `enable` — ids of your own extensions to install that the base would leave out.
- `disable` — ids of your own extensions to keep out that the base would install. Within one profile `disable` wins over `enable` for the same id. `enable` and `disable` gate the extensions kli discovers in `~/.config/kli/extensions/` and `<repo>/.kli/extensions/`, not the builtin tools.
- `settings` — a settings object that overlays the merged files while this profile is active. Use it to bind a profile to a default provider and model, a set of capabilities, or any other setting.

A profile may not reuse a builtin name (`interactive-terminal`, `headless`, `human-in-loop`, `autonomous`). kli warns and ignores any entry that does.

Once defined, a profile is selectable everywhere a builtin is: `--profile review`, `KLI_PROFILE=review`, the `profile` key, and `/profile review`. It also appears in the `/profile` list and in `/profile` tab completion.

For how `enable` and `disable` sit against the per-extension `/enable` and `/disable` commands, see [Restrict What kli Can Do](/kli/guides/restrict-what-kli-can-do) and the [settings reference](/kli/config/settings). For what an extension is and why retracting one mid-session is safe, see [The Live Image](/kli/concepts/the-live-image).
