Layering
Hyprpilot reads layered config. Each source overrides the one before it for the fields it sets, so you only write what you want to change.
The layers
- Compiled defaults — every knob has a working default, baked into the binary from
src/config/defaults.toml. - Global config —
~/.config/hyprpilot/config.{toml,json,yaml,yml}, or an explicit--config <path>. - Named config-layer profile —
~/.config/hyprpilot/profiles/<name>.{ext}, picked with--config-profile <name>orHYPRPILOT_CONFIG_PROFILE=<name>. patchesand--with-config— profile overlays applied at resolve time. See Patches and Ad-hoc Overlays.
Any layer can be any supported format — a YAML global config composes with a TOML config-layer profile. See Formats for extension discovery.
Merge rules
- Scalar fields overwrite — a later layer's value wins for the fields it sets.
- The keyed
agents/profileslists merge byid— a later layer's entry with a matchingidreplaces the earlier entry wholesale, and new ids append. There is no field-level merge inside a single entry. - The
patcheslist is additive — each layer's patches append to the earlier layers' list instead of replacing it, so the seeded default patch and your global patches survive a config-layer profile that adds more. See Patches → Additive across layers for how to neutralize an inherited patch.
~ and ${VAR} / ${env:VAR} in path-valued fields expand at consume time; relative paths resolve against the current directory.
Config-layer profile ≠ session profile
The word "profile" lives in two parallel namespaces — keep them apart:
| Concept | Addressed via | Purpose |
|---|---|---|
| Config-layer profile | --config-profile / HYPRPILOT_CONFIG_PROFILE | Layer a different config file overlay (e.g. work vs personal). |
| Session profile | profiles in config, picked via the positional [PROFILE] | Which agent + model + cwd + system prompt + MCPs a launch uses. See Profiles. |
A config-layer profile can itself define or override session profiles — that is the point: HYPRPILOT_CONFIG_PROFILE=work can swap your whole profiles registry.
Validation
After the layers merge, the whole config is validated in one pass:
- Unknown fields reject at parse time — every section is a closed shape, so a typo like
modle: …fails with an error naming the field. - Closed sets are enums —
provider,--log-levelvalues, and config formats reject unknown values at parse, not deep in a launch. - Cross-field references are checked —
profiles[].agentmust reference a realagents[].id, andprofile.defaultmust name a realprofiles[].id. - The
profileslist must be non-empty — a fresh install with no profile refuses to launch rather than guessing.
Validation failures abort startup with a readable field-path error, so a broken config never reaches the vendor CLI.
Where things live
| Path | What |
|---|---|
~/.config/hyprpilot/config.{toml,json,yaml,yml} | Global config. |
~/.config/hyprpilot/profiles/*.{ext} | Named config-layer overlays. |
~/.config/hyprpilot/skills/<slug>/SKILL.md | Skill bundles (default catalogue root). |
~/.config/hyprpilot/mcps/*.json | MCP catalogue files (your convention). |