preferredShell: optional non-empty string declaring the interactive shell; independent of Pi's tool execution shells.
os keys: win32, lnx, mac.
hosts keys: hostname, matched case-insensitively.
Each os or hosts entry needs a tools object with optional add and remove arrays of non-empty tool names.
Both maps are optional.
Unknown tool names are ignored with a warning.
Fold order: os first, then hosts; hosts wins per field.
No match: no change.
Sources, highest first: trusted project .pi/settings.json, user ~/.pi/agent/settings.json, empty default.
No flags or environment variables exist.
Project settings are read only when Pi trusts the project.
When both blocks exist, they deep-merge with project winning per key, down into individual os and hosts entries.
Arrays such as tools.add replace rather than concatenate.
An invalid block, including one invalid merged field, triggers a horst: Invalid horst ...; settings ignored warning.
Then no tool delta and no preferred shell apply; lower sources are not used as fallback.
Behavior
Injects host facts (<horst>) into the system prompt:
hostname, os, kernel, arch, cpu, memory, available account login shell, and configured preferred shell.
The login shell comes from the effective user's OS account record on Unix; Windows has no equivalent field.
The preferred shell is explicitly declared, not inferred from $SHELL or Pi's tool configuration.
Loads host facts lazily exactly once per process:
node:os getters plus one /etc/os-release read on Linux.
Shell preference is read at session start; reload Pi after changing settings.
Applies the configured tool delta once per session start on top of the
active tools.
Debug
Opt in through debug contract.
Safe events: session.start, session.shutdown, host.section.start, host.section.finish, host.section.error.
# horst
Per-host environment data and tool defaults for Pi.
## Install / load
Loaded through the root pi-ext package.
See [root README](../../README.md).
## Commands / tools / settings
- Commands:
none
- Tools:
none
- Settings:
`horst` block; see [Settings](#settings)
- Hooks:
`session_start`, `before_agent_start`
## Settings
```json
{
"horst": {
"preferredShell": "nu",
"os": {
"win32": { "tools": { "add": ["powershell"], "remove": ["bash"] } }
},
"hosts": {
"winbox": { "tools": { "remove": ["read"] } }
}
}
}
```
- `preferredShell`: optional non-empty string declaring the interactive shell; independent of Pi's tool execution shells.
- `os` keys: `win32`, `lnx`, `mac`.
- `hosts` keys: hostname, matched case-insensitively.
- Each `os` or `hosts` entry needs a `tools` object with optional `add` and `remove` arrays of non-empty tool names.
- Both maps are optional.
- Unknown tool names are ignored with a warning.
- Fold order: `os` first, then `hosts`; `hosts` wins per field.
- No match: no change.
Sources, highest first: trusted project `.pi/settings.json`, user `~/.pi/agent/settings.json`, empty default.
No flags or environment variables exist.
Project settings are read only when Pi trusts the project.
When both blocks exist, they deep-merge with project winning per key, down into individual `os` and `hosts` entries.
Arrays such as `tools.add` replace rather than concatenate.
An invalid block, including one invalid merged field, triggers a `horst: Invalid horst ...; settings ignored` warning.
Then no tool delta and no preferred shell apply; lower sources are not used as fallback.
## Behavior
- Injects host facts (`<horst>`) into the system prompt:
hostname, os, kernel, arch, cpu, memory, available account login shell, and configured preferred shell.
- The login shell comes from the effective user's OS account record on Unix; Windows has no equivalent field.
- The preferred shell is explicitly declared, not inferred from `$SHELL` or Pi's tool configuration.
- Loads host facts lazily exactly once per process:
`node:os` getters plus one `/etc/os-release` read on Linux.
- Shell preference is read at session start; reload Pi after changing settings.
- Applies the configured tool delta once per session start on top of the
active tools.
## Debug
Opt in through [debug contract](../DEBUG.md).
Safe events: `session.start`, `session.shutdown`, `host.section.start`, `host.section.finish`, `host.section.error`.