koshi0.1.0
Configuration

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.

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

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 in cells, or a percent of the split≥ 0.1.0
weight 2A relative share of the leftover space≥ 0.1.0
min 10Never shrink below this many cells≥ 0.1.0
preferred 30The size to aim for when there is room≥ 0.1.0

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.

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