Selection Behavior Improvements:
- Limit selection to parent services only (docker, nginx, postgresql, etc.)
- Skip sub-services in navigation (no longer select nginx sub-sites)
- Up/Down arrows now move between actionable services only
Visual Enhancement:
- Preserve original status colors in selection highlighting
- Selected services show blue background with status foreground colors
- Green text for active services, red for failed, even when selected
- Maintains visual health status information during selection
Selection Logic:
- Add parent service index mapping for accurate selection tracking
- Only count parent services in total service count
- Calculate proper parent service index from display line position
- Ensure selection highlights only apply to parent services
This creates a cleaner UX where users only select services they can
actually control (start/stop/restart) while maintaining visual health
status indicators through preserved status colors.
Visual Highlighting Fixes:
- Apply selection highlighting to individual text spans instead of entire paragraph
- Eliminates highlighting of empty space below services on single-service hosts
- Selection now only highlights actual service text content
Selection Logic Improvements:
- Add proper bounds checking in select_next() to prevent invalid selections
- Automatically clamp selection index when services are updated
- Add debug logging to track selection state and movement
Bounds Safety:
- Ensure selection index stays valid when service lists change
- Prevent out-of-bounds access during service updates
- Reset selection to last valid index when services are removed
This fixes the issues where:
1. Single service hosts showed empty space highlighting
2. Multi-service hosts had no visible selection cursor
3. Selection could become invalid when services changed
Service Selection Features:
- Add selection cursor for Services panel with visual highlighting
- Up/Down arrows move service selection instead of scrolling
- Track selected service for future action implementation
- Selection state maintained per host
Panel Navigation Improvements:
- Fix panel switching to only cycle through visible panels
- Dynamic panel list based on backup data availability
- Smart recovery when focused panel becomes invisible
- No more navigation to hidden backup panel
Backup Panel Scrolling Fix:
- Fix backup panel scroll to show actual repository content
- Replace static overflow indicator with proper scroll behavior
- Add scroll position indicators (above/below)
- Show all repositories when scrolling instead of truncated list
Navigation now works correctly with actual UI layout and
provides proper service selection for future action implementation.
- Remove Network panel from navigation cycle
- Fix system panel scrolling to work in both directions
- Add complete scroll support to Services and Backup panels
- Update panel cycling to System → Services → Backup only
- Enhance scroll indicators with proper bounds checking
- Clean up unused Network panel code and references
Resolves issues with non-functional up/down scrolling and
mystery network panel appearing during navigation.
The new keybindings (Shift+Tab, Up, Down, BackTab) weren't working because
the main app.rs event loop was only passing specific keys to the TUI app.
Added handling for:
- KeyCode::BackTab (Shift+Tab panel switching)
- KeyCode::Up (scroll up in focused panel)
- KeyCode::Down (scroll down in focused panel)
Now all keyboard navigation features work correctly.
- Add Typography::tree() style using blue Theme::highlight() color
- Update system, backup, and services widgets to use consistent blue tree styling
- Centralizes tree color management in theme module for easy maintenance
Restore "... and X more" indicators when panel content doesn't fit:
- System widget: Shows overflow for storage pools when area is too small
- Backup widget: Shows overflow for repository list when area is too small
- Maintains consistent formatting with existing services widget overflow
Update all tree symbols (└─, ├─) in system and backup widgets to use
Typography::secondary() style instead of raw text for consistent
text coloring throughout the interface.
Backup widget:
- Restructure to match new layout specification
- Add section headers: Latest backup, Disk, Repos
- Show timestamp with status icon and duration as sub-item
- Display disk info with product name, S/N, and usage in tree structure
- List repositories with archive count and size
- Remove old render methods and unused imports
System widget:
- Hide (Single) storage type label for cleaner display
- Add section headers: CPU, RAM, Storage as plain titles
- Remove status icons from section headers
- Keep status icons only on data lines (Load, Usage, /tmp, filesystems)
- Restore (Single) label for all storage types
- Improve visual hierarchy with clear section separation
- Replace findmnt with lsblk for efficient device name detection
- Fix tree indentation to align consistently with status icon text
- Hide '(Single)' label for single disk storage pools
- Device detection returns actual names (nvme0n1, sda) not UUID paths
- Remove Active users line from NixOS section
- Add status icons to CPU and RAM sections
- Restructure layout with proper tree symbols and spacing
- Add empty lines between sections for better readability
- Remove Storage header, show each filesystem as top-level item
- Fix tree indentation to match specification
- CPU shows load averages with frequency as sub-item
- RAM shows usage with /tmp as sub-item with status icon
- Add mount_point field to StoragePool struct
- Create mapping from pool names to mount points
- Update display to show user-friendly mount points (/, /mnt/steampool)
- Keep device detection for SMART data (temperature, wear)
- Resolves disk name confusion on different hosts
Implement agent version tracking to diagnose deployment issues:
- Add get_agent_hash() method to extract Nix store hash from executable path
- Collect system_agent_hash metric in NixOS collector
- Display "Agent Hash" in system panel under NixOS section
- Update metric filtering to include agent hash
This helps identify which version of the agent is actually running
when troubleshooting deployment or metric collection issues.
Update metric filtering to use exact metric names instead of prefix matching.
This resolves the issue where build version showed 'unknown' despite agent
correctly collecting the metric.
- Change from showing version to build format: 'hash dd/mm/yy H:M:S'
- Parse nixos-version output to extract short hash and format date
- Update system widget to display 'Build:' instead of 'Version:'
- Remove version/build_date fields in favor of single build string
- Follow TODO.md specification for NixOS section layout
- Add memory_tmp_usage_percent, memory_tmp_used_gb, memory_tmp_total_gb metric parsing
- Fix tmpfs display showing as —% —GB/—GB in dashboard
- System widget now properly receives and displays tmpfs metrics from memory collector
- Remove /tmp autodetection from disk collector (57 lines removed)
- Add tmpfs monitoring to memory collector with get_tmpfs_metrics() method
- Generate memory_tmp_* metrics for proper RAM-based tmpfs monitoring
- Fix type annotations in tmpfs parsing for compilation
- System widget now correctly displays tmpfs usage in RAM section
- Create NixOS collector for version and active users detection
- Add SystemWidget combining all system information in TODO.md layout
- Replace separate CPU/Memory widgets with unified system display
- Add tree structure for storage with drive temperature/wear info
- Support NixOS version, active users, load averages, memory usage
- Follow exact decimal formatting from specification
- Fix duplicate storage pool issue by clearing cache on agent startup
- Change storage pool header text to normal color for better readability
- Improve services panel tree icons with proper └─ symbols for last items
- Ensure fresh metrics data on each agent restart
Eliminate duplicate storage entries by removing old disk_count dependency.
Dashboard now uses pure auto-discovery of disk_{pool}_usage_percent metrics.
Fixes multiple storage instances (Storage 0, Storage 1, Storage root)
showing only proper tree structure format.
Add proper hierarchical tree display for storage pools and drives:
- Pool headers with status icons and type indication (Single/multi-drive)
- Individual drive lines with ├─ tree symbols and health status
- Usage summary with └─ end symbol and capacity status
- T: and W: prefixes for temperature and wear level metrics
- Themed status icons using StatusIcons::get_icon() with proper colors
- 2-space indentation for clean tree structure appearance
Replace flat storage display with beautiful tree format:
● Storage steampool (multi-drive):
├─ ● sdb T:35°C W:12%
├─ ● sdc T:38°C W:8%
└─ ● 78.1% 1250.3GB/1600.0GB
Uses agent-calculated status from NixOS-configured thresholds.
Update CLAUDE.md with complete implementation specification.
Restructure storage display to handle new individual metrics architecture:
- Parse disk_{pool}_* metrics instead of indexed disk_{index}_* format
- Support individual drive metrics disk_{pool}_{drive}_health/temperature/wear
- Display tree structure: "Storage {pool} ({type}): drive details"
- Show pool usage summary with individual drive health/temp/wear status
- Auto-discover storage pools and drives from metric patterns
- Maintain proper status aggregation from individual metrics
The dashboard now correctly displays the new enhanced disk collector output
with storage pools containing multiple drives and their individual metrics.
- Dashboard now automatically looks for /etc/cm-dashboard/dashboard.toml
- No need to specify --config flag when using standard NixOS deployment
- Fallback to manual config path if default not found
- Update help text to reflect optional config parameter
- Simplifies dashboard usage - just run 'cm-dashboard' without arguments
- Remove all unused configuration options from dashboard config module
- Eliminate hardcoded defaults - dashboard now requires config file like agent
- Keep only actually used config: zmq.subscriber_ports and hosts.predefined_hosts
- Remove unused get_host_metrics function from metric store
- Clean up missing module imports (hosts, utils)
- Make dashboard fail fast if no configuration provided
- Align dashboard config approach with agent configuration pattern
Add comprehensive hysteresis support to prevent status oscillation near
threshold boundaries while maintaining responsive alerting.
Key Features:
- HysteresisThresholds with configurable upper/lower limits
- StatusTracker for per-metric status history
- Default gaps: CPU load 10%, memory 5%, disk temp 5°C
Updated Components:
- CPU load collector (5-minute average with hysteresis)
- Memory usage collector (percentage-based thresholds)
- Disk temperature collector (SMART data monitoring)
- All collectors updated to support StatusTracker interface
Cache Interval Adjustments:
- Service status: 60s → 10s (faster response)
- Disk usage: 300s → 60s (more frequent checks)
- Backup status: 900s → 60s (quicker updates)
- SMART data: moved to 600s tier (10 minutes)
Architecture:
- Individual metric status calculation in collectors
- Centralized StatusTracker in MetricCollectionManager
- Status aggregation preserved in dashboard widgets
- Add support for both proxied and static nginx sites
- Proxied sites show 'P' prefix and check backend URLs
- Static sites check external HTTPS URLs
- Fix services panel column alignment for main services
- Keep 10-second timeout for all site checks
- Fix host_index calculation for localhost to use actual position in sorted list
- Remove incorrect assumption that localhost is always at index 0
- Host navigation (Tab key) now works correctly with all hosts in alphabetical order
Fixes issue where only 3 of 5 hosts were accessible via Tab navigation.
- Remove predefined host order that was causing random display order
- Sort hosts alphabetically for consistent title display
- Localhost is still auto-selected at startup but doesn't affect display order
- Title will now show: cmbox ● labbox ● simonbox ● srv01 ● srv02 ● steambox
Eliminates confusing random host order in dashboard title bar.
- Add has_data() method to BackupWidget to check if backup metrics exist
- Modify dashboard layout to conditionally show backup panel only when data exists
- When no backup data: system panel takes full left side height
- When backup data exists: system and backup panels share left side equally
Prevents empty backup panel from taking up screen space unnecessarily.
- Sort physical devices by name to prevent random HashMap iteration order
- Sort partitions within each device by disk index for consistency
- Eliminates flickering caused by disks changing positions randomly
The dashboard storage section now maintains stable disk order across updates.
- Add user_navigated_away flag to track manual navigation
- Only auto-switch to localhost if user hasn't manually navigated away
- Reset flag when host disconnects to allow auto-selection
- Preserves user's tab navigation choices while still prioritizing localhost initially
- Dashboard now switches to localhost even if another host is already selected
- Ensures localhost is always preferred regardless of connection order
- Resolves issue where srv01 connecting first would prevent localhost selection
- Always select localhost as default host at startup
- Order hosts with localhost first, then predefined sequence
- Display hostname status colors in title bar based on metric aggregation
- Add gethostname dependency for localhost detection
Removed unused widget subscription system, cache utilities, error variants,
theme functions, and struct fields. Replaced subscription-based widgets
with direct metric filtering. Build now completes with zero warnings.
Resolves widget data persistence issue where switching hosts left stale data
from the previous host displayed in widgets.
Key improvements:
- Add Clone derives to all widget structs (CpuWidget, MemoryWidget,
ServicesWidget, BackupWidget)
- Create HostWidgets struct to cache widget states per hostname
- Update TuiApp with HashMap<String, HostWidgets> for per-host storage
- Fix borrowing issues by cloning hostname before mutable self borrow
- Implement instant widget state restoration when switching hosts
Tab key host switching now displays cached widget data for each host
without stale information persistence between switches.
- Add KeyCode::Tab support to main dashboard event loop
- Add Tab key handling to TuiApp handle_input method
- Tab key now cycles to next host using existing navigate_host logic
- Host switching infrastructure was already implemented, just needed Tab key support
- Current host displayed in bold in title bar, other hosts shown normally
- Metrics filtered by selected host, full navigation working
- Add BackupCollector for reading TOML status files with disk space metrics
- Implement BackupWidget with disk usage display and service status details
- Fix backup script disk space parsing by adding missing capture_output=True
- Update backup widget to show actual disk usage instead of repository size
- Fix timestamp parsing to use backup completion time instead of start time
- Resolve timezone issues by using UTC timestamps in backup script
- Add disk identification metrics (product name, serial number) to backup status
- Enhance UI layout with proper backup monitoring integration