Configuration
Everything personal lives in ~/.config/loadout/config.yaml. It is the only file you maintain.
version: 1
paths: project_root: ~/Projects venv_root: ~/.venv
git: main_branch: main dev_branch: development
identities: - id: personal git_user: Your Name email: you@example.com ssh_key: ~/.ssh/id_ed25519 default: true
workspaces: - name: api path: ~/Projects/api/api.code-workspace tmux_session: api
hosts: - alias: staging hostname: staging.example.com user: deploy key: ~/.ssh/deploy
packs: [ansible, cloudflared]Every section is optional except version. A section you leave out simply produces no aliases — a configuration with no hosts generates no host shortcuts, and msh reports that it needs some.
The full field-by-field listing is in the configuration schema. This page is about how the file behaves.
Nothing personal is generated blindly
Section titled “Nothing personal is generated blindly”Config values reach the generated shell as data, not as text substitution you have to think about. Paths are written in $HOME form rather than with a tilde, because a tilde does not expand inside double quotes and an interpolated "~/Projects" produces a literal directory called ~. That was a real bug, and there is now a test that fails on any "~/ appearing in generated output.
local.yaml: what must not travel
Section titled “local.yaml: what must not travel”The same config.yaml landing on a laptop and a headless server will reference things that exist on only one of them.
Most of that needs no special handling. An entry whose binary or path is missing degrades to a doctor finding rather than generating something broken — that is what the requires mechanism is for, and it removes the need for a profile system.
For values that genuinely differ per machine rather than merely being absent, ~/.config/loadout/local.yaml overlays config.yaml:
# ~/.config/loadout/local.yaml — this machine onlypaths: project_root: /srv/workTwo files, one merge step, no profile machinery. local.yaml is never synced — that is its entire purpose. See Sync.
Scalars replace. Maps merge key by key. Lists replace wholesale, so an overlay that sets packs replaces the list rather than appending to it.
Validation
Section titled “Validation”loadout apply refuses to render an invalid configuration rather than generating something odd and letting you discover it later.
Errors name the file, the key, what was expected, and what to do:
loadout.toml:12 unknown key `git.user` expected one of: git.name, git.email, git.signing_key run `loadout doctor` to check the whole configA few rules are worth knowing because they exist to prevent silent breakage:
- Two credentials resolving to the same environment variable is rejected. Otherwise one would overwrite the other and the loser would be whichever sorted last.
- A credential active on an entry not in its
entrieslist is rejected. That state is always a typo. - A host password must be
cred:<name>, never a literal. See Credentials.
Editing it
Section titled “Editing it”Three ways, all writing the same file:
loadout init # create it, interactivelyloadout ui # browse and toggle in a browser$EDITOR ~/.config/loadout/config.yamlWhichever you use, the file is only half the story. Run loadout apply afterwards, or nothing in your shell changes.
Where your configuration shows up
Section titled “Where your configuration shows up”loadout describe <command> names the configuration sections that shape a given command, so you can work backwards from a command that is not behaving to the section it reads:
loadout describe pwreports that pw is shaped by workspaces, editors and paths.project_root, and tells you which of those are currently satisfied on this machine.