KOSHI0.4.0
Configuration
v0.4configurationfield manual

Profiles

Save a whole desk — tabs, pane layouts, commands, working directories, and environment values — and open it with koshi --profile.

A profile is a saved session layout. Load one by name:

koshi --profile dev

That reads profile/dev.kdl instead of opening a single shell pane. The file lives in a profile/ subdirectory of the config directory.

A profile is read once, when the session starts. koshi attach joins a session as it is now and never re-applies a profile.

If anything in the profile is wrong, the whole profile is dropped and koshi starts one shell instead. A missing named profile falls back the same way. koshi config check validates every saved profile.

Structure

A profile is one or more tab blocks, plus a required version.

NodeMeaningSince
version <n>Required schema version≥ 0.1.0
tab { … }One tab; its children are the pane arrangement≥ 0.1.0
pane { … }A terminal pane≥ 0.1.0
horizontal { … }Split its children left to right≥ 0.1.0
vertical { … }Split its children top to bottom≥ 0.1.0
stack { … }Children share one rectangle; one is expanded≥ 0.1.0
lockStart the session's first terminal with input locked≥ 0.4.0

A plugin "<name>" node parses and validates, and no koshi build launches it. A profile holding one starts one shell instead.

Inside a pane

KeyValueSince
command "prog" "arg"…The program and its arguments. Omit for the default shell≥ 0.1.0
cwd "/path"Working directory, used as written — absolute, and ~ is not expanded≥ 0.1.0
env "NAME" "VALUE"One environment variable for this pane; repeatable≥ 0.1.0
focusStart with this pane focused; one per tab≥ 0.1.0

Omitting cwd inherits the directory koshi was launched from. Launching from /home/me/proj starts that pane there; an explicit cwd "/srv/app" still wins.

Sizing

Sizing keys are only valid on a direct child of horizontal or vertical. Without any, children share the space equally.

KeyValueSince
size 40 / size "60%"A fixed size: 1–65535 cells, or 1–100 percent of the split≥ 0.1.0
weight 2A relative share of the leftover space, 1–4294967295≥ 0.1.0
min 10Never shrink below this many cells, 1–65535≥ 0.1.0
preferred 30The size to aim for when there is room, 1–65535 cells≥ 0.1.0

size and weight are the same slot: give one of the two, once.

Stacks and focus

Inside a stack, expanded marks the one member shown open; the rest collapse to a one-row header.

focus inside a pane marks the pane that starts focused — one per tab. focus as a direct child of a tab marks the tab that starts active — one per profile. Without either, the first pane of the first tab starts focused.

Starting locked

A bare top-level lock node starts the first terminal in locked input mode. Keys go straight to the focused program until koshi unlock, koshi toggle-lock, or <C-l> releases it. The node takes no value or children, and a later terminal starts unlocked.

version 1
lock

tab {
    pane {
        command "htop"
    }
}

A profile using every feature

profile/dev.kdl
// profile/dev.kdl — a complete profile using every feature.
version 1

tab {
    // a horizontal split: editor on the left (60%), a tools column (40%) right
    horizontal {
        pane {
            command "nvim" "src/main.rs"    // program + its arguments
            cwd "/home/me/proj"             // absolute path (~ is not expanded)
            env "RUST_LOG" "debug"          // one env var...
            env "NO_COLOR" "1"              // ...repeat for more
            size "60%"                      // fixed share of the split
            focus                           // this pane starts focused
        }
        vertical {
            size "40%"
            pane {
                command "cargo" "watch" "-x" "test"
                cwd "/home/me/proj"
                weight 2                     // twice the leftover share of...
                min 5                        // ...but never below 5 rows,
                preferred 20                 // ...aiming for 20 when there's room
            }
            pane {
                cwd "/home/me/proj"          // no command → the default shell
                weight 1
            }
        }
    }
}

tab {
    focus                                    // this tab starts active

    // a stack: members share one rectangle; `expanded` is the open one
    stack {
        pane {
            command "journalctl" "-f"
        }
        pane {
            command "htop"
            expanded                         // this member starts open
        }
    }
}

On this page