# Overview (/docs/v0.1/configuration)



koshi reads four optional KDL file types. With none present, built-in defaults
apply. Every file that does exist must declare a supported `version`.

| File                                                        | What it sets                                                                         |
| ----------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| [`koshi.kdl`](/docs/v0.1/configuration/koshi-kdl)           | Theme, pane, scrollback, layout, mouse, copy, terminal, logging, and update settings |
| [`themes/<name>.kdl`](/docs/v0.1/configuration/themes)      | Interface colours, selected by `theme "<name>"`                                      |
| [`keybinding.kdl`](/docs/v0.1/configuration/keybinding-kdl) | Key bindings and the modes they live in                                              |
| [`profile/<name>.kdl`](/docs/v0.1/configuration/profiles)   | A saved layout, opened with `koshi --profile <name>`                                 |

## Where the files go [#where-the-files-go]

The two top-level files sit in the config directory. Themes and profiles use
their own subdirectories.

| Platform | Config directory                      |
| -------- | ------------------------------------- |
| Linux    | `~/.config/koshi`                     |
| macOS    | `~/Library/Application Support/koshi` |
| Windows  | `%APPDATA%\koshi\config`              |

```
<config dir>/
    koshi.kdl
    keybinding.kdl
    themes/
        midnight.kdl
        solarized.kdl
    profile/
        dev.kdl
        writing.kdl
```

koshi has no config-path override. Linux still follows `XDG_CONFIG_HOME`.

```bash
koshi config path
```

## Versions and migration [#versions-and-migration]

Every file declares one top-level `version` with one integer argument, starting
at 1, and no child block:

```kdl
version 1
```

```bash
koshi config check     # validate every present file, change nothing
koshi config migrate   # validate, then apply registered schema steps
```

`check` fails on missing versions, bad KDL, bad values, unknown keys, and
unsupported versions, and reports errors from all files together.

`migrate` validates every file before writing, applies each version step in
order, and validates after each step. Invalid input or a missing step stops
migration before any file is written. Changed files are replaced atomically,
one at a time; symlinks stay and their targets change. A write error lists the
files already completed and marks the failed one as possibly changed.

The current schema version is `1`, so valid version `1` files are reported as
current and left alone. Migration never runs during startup and never repairs
invalid config.

## When a file has a mistake [#when-a-file-has-a-mistake]

* **`koshi.kdl` and themes are field-partial.** A bad field keeps its default
  and the other valid fields still apply. koshi logs each skipped field.
* **Keybindings and profiles are all-or-nothing.** Any error drops the whole
  file.
* **Unknown keys name the nearest valid key.** `min-col 2` produces
  ``did you mean `min-cols`?``. `koshi config check` treats that typo as an
  error even though startup would keep the other fields.
* **A missing or invalid theme** falls back to the built-in `default` colours
  and logs why.

## Explain one setting [#explain-one-setting]

```bash
koshi config explain scrollback.lines
```

Prints which file the setting belongs to, its default, and what it does.
