diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-05-15 15:14:19 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-05-15 15:14:19 +0300 |
| commit | 4bfc3a89c570aea8c9e4c91a7b249b50c112f1d2 (patch) | |
| tree | 6141328f8d71220f26ad2c70967df368b8940763 | |
| parent | 7c636e97f4568583651de3bc8c8550a3bab54743 (diff) | |
config: split experimental settings from advanced
| -rw-r--r-- | .pi/docs/CONFIGURATION.md | 34 | ||||
| -rw-r--r-- | src/app/mod.rs | 15 | ||||
| -rw-r--r-- | src/client/mod.rs | 2 | ||||
| -rw-r--r-- | src/config/io.rs | 8 | ||||
| -rw-r--r-- | src/config/model.rs | 36 | ||||
| -rw-r--r-- | src/main.rs | 11 |
6 files changed, 76 insertions, 30 deletions
diff --git a/.pi/docs/CONFIGURATION.md b/.pi/docs/CONFIGURATION.md index 24bbe8c5..4336185e 100644 --- a/.pi/docs/CONFIGURATION.md +++ b/.pi/docs/CONFIGURATION.md @@ -44,12 +44,13 @@ Reloadable now: - `ui.agent_panel_scope` - `ui.toast.delivery` - server-side `ui.sound` policy; attached thin clients refresh local sound config after a successful sound-policy change +- `experimental.kitty_graphics` - `advanced.scrollback_limit_bytes` for panes created after reload - `ui.sidebar_width` as the default width; current width updates only while it is still config-owned Startup-only or special-case: - `onboarding` does not reopen onboarding during reload -- `advanced.allow_nested` is checked before launch and needs a restart +- `experimental.allow_nested` is checked before launch and needs a restart - existing pane scrollback buffers are not resized during reload - terminal notifications and sounds are client-local side effects and are sent to the foreground attached client @@ -365,20 +366,20 @@ available agent keys: - `droid` - `amp` -## advanced +## experimental ```toml -[advanced] +[experimental] allow_nested = false -scrollback_limit_bytes = 10000000 +kitty_graphics = false ``` ### options | option | default | description | |--------|---------|-------------| -| `advanced.allow_nested` | `false` | allow launching herdr from inside a herdr-managed pane | -| `advanced.scrollback_limit_bytes` | `10000000` | maximum scrollback buffer size in bytes retained per pane terminal | +| `experimental.allow_nested` | `false` | allow launching herdr from inside a herdr-managed pane | +| `experimental.kitty_graphics` | `false` | enable experimental local Kitty graphics rendering for attached clients | ### nested launches @@ -386,6 +387,25 @@ By default, herdr blocks nested launches when `HERDR_ENV=1` is already present. Set `allow_nested = true` only for debugging or intentionally nested setups. +### Kitty graphics + +`kitty_graphics` enables experimental local Kitty graphics rendering for attached clients. + +It requires a Kitty graphics-compatible outer terminal. + +## advanced + +```toml +[advanced] +scrollback_limit_bytes = 10000000 +``` + +### options + +| option | default | description | +|--------|---------|-------------| +| `advanced.scrollback_limit_bytes` | `10000000` | maximum scrollback buffer size in bytes retained per pane terminal | + ### scrollback `scrollback_limit_bytes` limits retained terminal scrollback per pane. @@ -394,7 +414,7 @@ The default matches Ghostty's `scrollback-limit` value. Set `scrollback_limit_bytes = 0` to disable pane scrollback entirely. -The old `advanced.scrollback_lines` key is still accepted as a compatibility alias, but it uses the same byte-based value. +The legacy `scrollback_lines` key is still accepted inside `[advanced]`, but it uses the same byte-based value. ## environment variables diff --git a/src/app/mod.rs b/src/app/mod.rs index b56e8fc9..7c3bae76 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -197,7 +197,7 @@ impl App { event_hub: crate::api::EventHub, ) -> Self { let (prefix_code, prefix_mods) = config.prefix_key(); - crate::kitty_graphics::set_enabled(config.advanced.kitty_graphics); + crate::kitty_graphics::set_enabled(config.experimental.kitty_graphics); let (event_tx, event_rx) = mpsc::channel::<AppEvent>(64); let render_notify = Arc::new(Notify::new()); let render_dirty = Arc::new(AtomicBool::new(false)); @@ -370,7 +370,7 @@ impl App { mouse_capture: config.ui.mouse_capture, confirm_close: config.ui.confirm_close, show_agent_labels_on_pane_borders: config.ui.show_agent_labels_on_pane_borders, - kitty_graphics_enabled: config.advanced.kitty_graphics, + kitty_graphics_enabled: config.experimental.kitty_graphics, pane_scrollback_limit_bytes: config.advanced.scrollback_limit_bytes, accent: crate::config::parse_color(&config.ui.accent), sound: config.ui.sound.clone(), @@ -718,13 +718,16 @@ impl App { self.state.toast_config = config.ui.toast.clone(); } - if !invalid_section("advanced") { + if !invalid_section("experimental") { let was_kitty_graphics_enabled = self.state.kitty_graphics_enabled; - self.state.kitty_graphics_enabled = config.advanced.kitty_graphics; - crate::kitty_graphics::set_enabled(config.advanced.kitty_graphics); - if was_kitty_graphics_enabled && !config.advanced.kitty_graphics { + self.state.kitty_graphics_enabled = config.experimental.kitty_graphics; + crate::kitty_graphics::set_enabled(config.experimental.kitty_graphics); + if was_kitty_graphics_enabled && !config.experimental.kitty_graphics { let _ = crate::kitty_graphics::clear_all_host_graphics(); } + } + + if !invalid_section("advanced") { self.state.pane_scrollback_limit_bytes = config.advanced.scrollback_limit_bytes; } diff --git a/src/client/mod.rs b/src/client/mod.rs index 50a54ef3..1758ffdc 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -309,7 +309,7 @@ pub fn run_client() -> io::Result<()> { let loaded_config = crate::config::Config::load(); let sound_config = loaded_config.config.ui.sound; - let kitty_graphics_enabled = loaded_config.config.advanced.kitty_graphics; + let kitty_graphics_enabled = loaded_config.config.experimental.kitty_graphics; let socket_path = client_socket_path(); crate::logging::startup("client"); diff --git a/src/config/io.rs b/src/config/io.rs index 16602972..60eb54d8 100644 --- a/src/config/io.rs +++ b/src/config/io.rs @@ -166,6 +166,14 @@ fn load_live_config_from_str(content: &str) -> Result<LoadedConfig, Vec<String>> &mut invalid_sections, |section| config.advanced = section, ); + load_live_section( + table, + "experimental", + "experimental config", + &mut diagnostics, + &mut invalid_sections, + |section| config.experimental = section, + ); Ok(LoadedConfig { config, diff --git a/src/config/model.rs b/src/config/model.rs index a8485fb0..8ea52724 100644 --- a/src/config/model.rs +++ b/src/config/model.rs @@ -56,6 +56,7 @@ pub struct Config { pub keys: KeysConfig, pub ui: UiConfig, pub advanced: AdvancedConfig, + pub experimental: ExperimentalConfig, } #[derive(Debug)] @@ -150,13 +151,18 @@ pub struct UiConfig { #[derive(Debug, Deserialize)] #[serde(default)] pub struct AdvancedConfig { + /// Maximum scrollback buffer size in bytes retained per pane terminal. Default: 10000000. + #[serde(alias = "scrollback_lines")] + pub scrollback_limit_bytes: usize, +} + +#[derive(Debug, Default, Deserialize)] +#[serde(default)] +pub struct ExperimentalConfig { /// Allow launching herdr inside an existing herdr pane. Default: false. pub allow_nested: bool, /// Experimental local Kitty graphics rendering for attached clients. Default: false. pub kitty_graphics: bool, - /// Maximum scrollback buffer size in bytes retained per pane terminal. Default: 10000000. - #[serde(alias = "scrollback_lines")] - pub scrollback_limit_bytes: usize, } impl Default for KeysConfig { @@ -242,8 +248,6 @@ impl<'de> Deserialize<'de> for ToastConfig { impl Default for AdvancedConfig { fn default() -> Self { Self { - allow_nested: false, - kitty_graphics: false, scrollback_limit_bytes: DEFAULT_SCROLLBACK_LIMIT_BYTES, } } @@ -364,27 +368,35 @@ delivery = "terminal" #[test] fn kitty_graphics_default_off_and_parse() { let config = Config::default(); - assert!(!config.advanced.kitty_graphics); + assert!(!config.experimental.kitty_graphics); let toml = r#" -[advanced] +[experimental] kitty_graphics = true "#; let config: Config = toml::from_str(toml).unwrap(); - assert!(config.advanced.kitty_graphics); + assert!(config.experimental.kitty_graphics); } #[test] - fn advanced_config_parses() { + fn experimental_config_parses() { let toml = r#" -[advanced] +[experimental] allow_nested = true kitty_graphics = true +"#; + let config: Config = toml::from_str(toml).unwrap(); + assert!(config.experimental.allow_nested); + assert!(config.experimental.kitty_graphics); + } + + #[test] + fn advanced_config_parses() { + let toml = r#" +[advanced] scrollback_limit_bytes = 12345 "#; let config: Config = toml::from_str(toml).unwrap(); - assert!(config.advanced.allow_nested); - assert!(config.advanced.kitty_graphics); assert_eq!(config.advanced.scrollback_limit_bytes, 12345); } diff --git a/src/main.rs b/src/main.rs index 92e6220d..ecfb9f07 100644 --- a/src/main.rs +++ b/src/main.rs @@ -159,12 +159,14 @@ const DEFAULT_CONFIG: &str = r##"# herdr configuration # [ui.sound.agents] # droid = "off" -[advanced] +[experimental] # Allow launching herdr from inside a herdr-managed pane. # allow_nested = false # Experimental local Kitty graphics rendering for attached clients. -# Requires a Kitty graphics-compatible outer terminal. Detach/headless replay is not supported yet. +# Requires a Kitty graphics-compatible outer terminal. # kitty_graphics = false + +[advanced] # Maximum scrollback buffer size in bytes retained per pane terminal. # Matches Ghostty's default scrollback-limit behavior. # scrollback_limit_bytes = 10000000 @@ -175,7 +177,7 @@ fn should_block_nested(config: &config::Config) -> bool { } fn should_block_nested_for_env(config: &config::Config, herdr_env: Option<&str>) -> bool { - !config.advanced.allow_nested && herdr_env == Some(HERDR_ENV_VALUE) + !config.experimental.allow_nested && herdr_env == Some(HERDR_ENV_VALUE) } fn random_nested_message() -> &'static str { @@ -539,7 +541,8 @@ mod tests { #[test] fn nested_herdr_does_not_block_when_allowed() { - let config: config::Config = toml::from_str("[advanced]\nallow_nested = true\n").unwrap(); + let config: config::Config = + toml::from_str("[experimental]\nallow_nested = true\n").unwrap(); assert!(!should_block_nested_for_env(&config, Some(HERDR_ENV_VALUE))); } |
