Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/APPROVED_CONTRIBUTORS
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,4 @@ MattJColes
brabli
aneym
1jehuang
abhishekvtangod
6 changes: 3 additions & 3 deletions docs/next/website/src/content/docs/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -261,14 +261,14 @@ The sidebar is the main Herdr dashboard. Search `ui.` in the [Config reference](

Set `tab_bar_position = "bottom"` under `[ui]` to place the desktop tab row below the terminal panes. Prefix, Navigate, Copy, and Resize mode bars temporarily replace the bottom tab row while active. The default is `"top"`.

Agent status uses compact colored dots by default. To distinguish blocked, working, done, idle, and unknown states by shape as well as color, choose **distinct symbols** in Settings or configure:
Agent status uses distinct static symbols by default so blocked, working, done, idle, and unknown states differ by shape as well as color. To keep the compact color-only dots, choose **color dots** in Settings or configure:

```toml
[ui]
status_indicators = "symbols"
status_indicators = "dots"
```

The symbols are static, so this option does not enable spinner animation.
Symbols remain static, so the default still does not enable spinner animation.

### Sidebar row layouts

Expand Down
2 changes: 1 addition & 1 deletion docs/next/website/src/data/config-reference.json
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,7 @@
{
"key": "ui.status_indicators",
"type": "enum",
"default": "\"dots\"",
"default": "\"symbols\"",
"description": "Choose compact color dots or distinct static symbols for agent states.",
"values": [
"dots",
Expand Down
6 changes: 3 additions & 3 deletions src/app/input/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ mod tests {
fn settings_indicator_choice_returns_save_action() {
let mut state = state_with_workspaces(&["test"]);
open_settings_at(&mut state, SettingsSection::Indicators);
state.settings.list.selected = 1;
state.settings.list.selected = 0;

let action = update_settings_state(
&mut state,
Expand All @@ -530,10 +530,10 @@ mod tests {
assert_eq!(
action,
Some(SettingsAction::SaveStatusIndicators(
StatusIndicatorStyle::Symbols
StatusIndicatorStyle::Dots
))
);
assert_eq!(state.status_indicators, StatusIndicatorStyle::Dots);
assert_eq!(state.status_indicators, StatusIndicatorStyle::Symbols);
assert_eq!(state.mode, Mode::Settings);
}

Expand Down
8 changes: 4 additions & 4 deletions src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3460,17 +3460,17 @@ mod tests {
let mut app = test_app();
assert_eq!(
app.state.status_indicators,
crate::config::StatusIndicatorStyle::Dots
crate::config::StatusIndicatorStyle::Symbols
);

app.save_status_indicators(crate::config::StatusIndicatorStyle::Symbols);
app.save_status_indicators(crate::config::StatusIndicatorStyle::Dots);

assert_eq!(
app.state.status_indicators,
crate::config::StatusIndicatorStyle::Symbols
crate::config::StatusIndicatorStyle::Dots
);
let content = std::fs::read_to_string(&path).unwrap();
assert!(content.contains("status_indicators = \"symbols\""));
assert!(content.contains("status_indicators = \"dots\""));
assert!(app.state.config_diagnostic.is_none());

std::env::remove_var(crate::config::CONFIG_PATH_ENV_VAR);
Expand Down
2 changes: 1 addition & 1 deletion src/app/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1874,7 +1874,7 @@ impl AppState {
sidebar_collapsed_mode: crate::config::SidebarCollapsedModeConfig::Compact,
sidebar_section_split: 0.5,
agent_panel_sort: AgentPanelSort::Spaces,
status_indicators: crate::config::StatusIndicatorStyle::Dots,
status_indicators: crate::config::StatusIndicatorStyle::Symbols,
agent_view_override: None,
sidebar_agents: crate::config::AgentsSidebarConfig::default(),
sidebar_spaces: crate::config::SpacesSidebarConfig::default(),
Expand Down
12 changes: 6 additions & 6 deletions src/config/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ enum LegacyAgentPanelScopeConfig {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize, Default)]
#[serde(rename_all = "lowercase")]
pub enum StatusIndicatorStyle {
#[default]
Dots,
#[default]
Symbols,
}

Expand Down Expand Up @@ -1059,7 +1059,7 @@ impl Default for UiConfig {
tab_bar_position: TabBarPositionConfig::Top,
agent_panel_sort: AgentPanelSortConfig::Spaces,
_legacy_agent_panel_scope: None,
status_indicators: StatusIndicatorStyle::Dots,
status_indicators: StatusIndicatorStyle::Symbols,
sidebar: SidebarConfig::default(),
accent: "cyan".into(),
toast: ToastConfig::default(),
Expand Down Expand Up @@ -1284,20 +1284,20 @@ agent_panel_scope = "current"
}

#[test]
fn status_indicator_style_defaults_to_dots_and_parses_symbols() {
fn status_indicator_style_defaults_to_symbols_and_parses_dots() {
assert_eq!(
Config::default().ui.status_indicators,
StatusIndicatorStyle::Dots
StatusIndicatorStyle::Symbols
);

let config: Config = toml::from_str(
r#"
[ui]
status_indicators = "symbols"
status_indicators = "dots"
"#,
)
.unwrap();
assert_eq!(config.ui.status_indicators, StatusIndicatorStyle::Symbols);
assert_eq!(config.ui.status_indicators, StatusIndicatorStyle::Dots);
}

#[test]
Expand Down
6 changes: 3 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,9 +326,9 @@ const DEFAULT_CONFIG: &str = r##"# herdr configuration
# "workspaces" is accepted as an alias for "spaces".
# agent_panel_sort = "spaces"

# Agent status indicators: "dots" preserves the compact color marks; "symbols" uses
# distinct static glyphs for blocked, working, done, idle, and unknown states.
# status_indicators = "dots"
# Agent status indicators: "symbols" (default) uses distinct static glyphs for blocked,
# working, done, idle, and unknown states. "dots" preserves the compact color marks.
# status_indicators = "symbols"

# Expanded agent rows. Built-ins are state_icon, state_text, workspace, tab, pane, agent,
# terminal_title, and terminal_title_stripped.
Expand Down
4 changes: 2 additions & 2 deletions tests/cross_area.rs
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,7 @@ fn cross_area_agent_process_survives_detach_and_reattach() {
client_handshake(&mut client_b, CURRENT_PROTOCOL, 80, 24);
let saw_working_on_client =
wait_for_frame_matching(&mut client_b, Duration::from_secs(5), |frame| {
frame_contains_colored_symbol(frame, "", (249, 226, 175))
frame_contains_colored_symbol(frame, "", (249, 226, 175))
})
.expect("frame decoding should succeed");
assert!(
Expand All @@ -864,7 +864,7 @@ fn cross_area_agent_process_survives_detach_and_reattach() {

let saw_blocked_on_client =
wait_for_frame_matching(&mut client_b, Duration::from_secs(5), |frame| {
frame_contains_colored_symbol(frame, "", (243, 139, 168))
frame_contains_colored_symbol(frame, "×", (243, 139, 168))
})
.expect("frame decoding should succeed");
assert!(
Expand Down
Loading