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 devThat 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.
| Node | Meaning | Since |
|---|---|---|
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 |
lock | Start the session's first terminal with input locked | ≥ 0.4.0 |
Inside a pane
| Key | Value | Since |
|---|---|---|
command "prog" "arg"… | The program and its arguments. Omit for the default shell | ≥ 0.1.0 |
cwd "/path" | Working directory, used as written. ~ is not expanded, so give an absolute path | ≥ 0.1.0 |
env "NAME" "VALUE" | One environment variable for this pane; repeatable | ≥ 0.1.0 |
focus | The session's first terminal starts 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.
| Key | Value | Since |
|---|---|---|
size 40 / size "60%" | A fixed size: 1–65535 cells, or 1–100 percent of the split | ≥ 0.1.0 |
weight 2 | A relative share of the leftover space, 1–4294967295 | ≥ 0.1.0 |
min 10 | Never shrink below this many cells, 1–65535 | ≥ 0.1.0 |
preferred 30 | The 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 the session's first terminal focuses in
that tab — one per tab. focus as a direct child of a tab marks the tab the
first terminal opens on — one per profile. Without either, the first terminal
opens on the first tab and focuses the first pane that shows in each tab; in a
stack, that is the expanded member.
Every terminal that attaches later opens on the first tab, focused on its first pane that shows. A client that focuses another member of a stack sees that member open on its own screen.
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 2
lock
tab {
pane {
command "htop"
}
}A profile using every feature
// profile/dev.kdl — a complete profile using every feature.
version 2
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 // the first terminal focuses this pane
}
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 // the first terminal opens on this tab
// a stack: members share one rectangle; `expanded` is the open one
stack {
pane {
command "journalctl" "-f"
}
pane {
command "htop"
expanded // this member starts open
}
}
}keybinding.kdl
Rebind koshi's keys — leader, chord timeouts, key grammar, repeating keys, and the mode blocks for normal, locked, pane moves, the floating pane tray, and the notification center.
Koshi FAQ
Answers about Koshi persistent sessions, panes, remote access, Windows support, terminal images, configuration, and cost.