Skip to content

feat: add warning/critical thresholds to context window segment#42

Open
ekain-fr wants to merge 14 commits intoHaleclipse:masterfrom
ekain-fr:feat/context-window-thresholds
Open

feat: add warning/critical thresholds to context window segment#42
ekain-fr wants to merge 14 commits intoHaleclipse:masterfrom
ekain-fr:feat/context-window-thresholds

Conversation

@ekain-fr
Copy link
Contributor

@ekain-fr ekain-fr commented Oct 10, 2025

Summary

Extends threshold-based color and bold text support to the context window segment, matching the implementation from usage segments (5-hour/7-day). This provides visual feedback when context usage exceeds configurable warning and critical thresholds.

⚠️ Dependency

This PR depends on PR #41 and should not be merged until #41 is merged first.

Changes

Core Implementation

src/core/segments/context_window.rs:

  • Add get_color_for_utilization() method
    • Checks utilization against warning_threshold (default 60%) and critical_threshold (default 80%)
    • Returns appropriate color override based on threshold level
  • Add should_be_bold() method
    • Determines if text should be bold based on threshold configuration
    • Supports per-threshold bold flags (warning_bold, critical_bold)
  • Integrate threshold logic into collect() method

TUI Integration

src/ui/app.rs, src/ui/components/settings.rs:

  • Include ContextWindow in threshold segment checks
  • Enables 6 threshold configuration fields in TUI:
    • Warning/Critical thresholds (percentage values)
    • Warning/Critical colors (16-color palette)
    • Warning/Critical bold flags (boolean)
CleanShot 2025-10-10 at 18 20 18@2x

Theme Configuration

All 9 theme files (theme_*.rs):

  • Add threshold options to context_window_segment() functions
  • Default configuration:
    • warning_threshold: 60%
    • critical_threshold: 80%
    • warning_color: c16=11 (bright yellow)
    • critical_color: c16=9 (bright red)
  • Bold text behavior:
    • Cometix & Gruvbox themes: Both warning and critical use bold (warning_bold: true, critical_bold: true)
    • All other themes: Only critical uses bold (warning_bold: false, critical_bold: true)

Default Behavior

  • Below 60%: Uses default segment colors (magenta/purple)
  • 60-79% (Warning): Yellow text, normal weight (bold in Cometix/Gruvbox)
  • 80%+ (Critical): Red text, bold weight

Testing

  • ✅ Compiles successfully with cargo build --release
  • ✅ All 9 themes updated consistently
  • ✅ TUI configurator recognizes context window as threshold segment
  • ✅ Threshold configuration fields appear in settings panel

Files Changed

12 files changed, 358 insertions(+), 13 deletions(-)

  • src/core/segments/context_window.rs (+106 lines)
  • src/ui/app.rs (1 line change)
  • src/ui/components/settings.rs (1 line change)
  • src/ui/themes/*.rs (9 files, +29 lines each for threshold configs)

Related


🤖 Generated with Claude Code

Co-Authored-By: Claude noreply@anthropic.com

Summary by Sourcery

Enable configurable warning and critical thresholds across context window and usage segments. This PR adds dynamic color and bold text overrides based on utilization, introduces dedicated 5-hour and 7-day usage segments sharing a unified API cache, centralizes color handling in a new utility module, and updates the TUI, theme presets, documentation, and status line rendering to support these features.

New Features:

  • Add warning and critical utilization thresholds to ContextWindow segment for dynamic color and bold text overrides
  • Introduce Usage5Hour and Usage7Day segments with shared API cache and threshold-based visual warnings
  • Add color_utils module for ANSI color JSON serialization and ratatui color conversion

Enhancements:

  • Extend TUI configurator to display and edit threshold options (warning/critical percentages, colors, bold flags) for usage and context window segments
  • Update all built-in theme presets and segment configurations to include default warning/critical threshold settings
  • Enhance preview component and status line generator to apply threshold-based color and bold overrides
  • Add helper functions to format 5-hour and 7-day reset times and expose cache loading for usage segments

Documentation:

  • Update README to document new usage segments and threshold-based color configuration
  • Add CHANGELOG entry for version 1.0.9 detailing new segments and threshold features

ekain-fr and others added 13 commits October 9, 2025 15:00
Add two new usage segments for enhanced API usage monitoring:
- Usage5Hour: Displays 5-hour usage with reset time (24% -> 11am)
- Usage7Day: Displays 7-day usage with reset datetime (12% -> Oct 9, 5am)

Features:
- Efficient shared API cache to minimize redundant calls
- Dynamic circle icons based on utilization level
- Automatic UTC to local timezone conversion
- Both segments disabled by default (opt-in)

Technical changes:
- Updated API cache structure with separate reset time fields
- Added time formatting functions for 5-hour and 7-day displays
- Updated all 9 built-in themes to include new segments
- Enhanced UI components with new segment name mappings
- Made ApiUsageCache public for cross-module access

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Add comprehensive documentation for developers running a forked version
of CCometixLine, including:
- How to rebuild after pulling updates
- Installation options (local vs system-wide)
- Steps to clear old theme cache when new segments are added
- Note about binary naming (ccometixline -> ccline)

Also includes version bump to 1.0.9 in Cargo.lock.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…segments

Replace ASCII arrow (->) with Unicode rightwards arrow (→) for cleaner
display in the 5-hour and 7-day usage segments.

Changes:
- usage_5hour.rs: Format now shows "24% → 11am"
- usage_7day.rs: Format now shows "12% → Oct 9, 5am"
- README.md: Updated documentation examples to reflect new format

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Change 7-day usage segment format from "Oct 9, 5am" to "Oct 9:5am"
for more compact display by replacing comma-space with colon.

Changes:
- usage.rs: Updated format_7day_reset_time() to use colon separator
- README.md: Updated documentation example to show "Oct 9:5am"

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Add dynamic color changing for Usage5Hour and Usage7Day segments based on
utilization thresholds. This provides visual warnings when API usage
approaches limits.

Features:
- Configurable warning threshold (default: 60%)
- Configurable critical threshold (default: 80%)
- Custom colors for warning and critical states
- Independent configuration per segment
- Supports c16, c256, and RGB color formats

Changes:
- theme_*.rs: Added threshold options to usage segment definitions
  - warning_threshold: 60
  - critical_threshold: 80
  - warning_color: c256 226 (yellow)
  - critical_color: c256 196 (red)
- usage_5hour.rs: Implemented get_color_for_utilization() to determine
  threshold-based colors and add text_color_override to metadata
- usage_7day.rs: Same threshold logic as usage_5hour
- statusline.rs: Check for text_color_override in metadata and apply
  instead of default segment colors
- README.md: Added comprehensive documentation for threshold configuration

Usage example:
```toml
[[segments]]
id = "usage_5hour"
[segments.options]
warning_threshold = 60
critical_threshold = 80
warning_color.c256 = 226  # Yellow
critical_color.c256 = 196  # Red
```

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Implement full TUI support for threshold-based warning colors. Users can
now interactively configure warning/critical thresholds and colors directly
in the TUI configurator without editing config files.

Features:
- New threshold fields shown for Usage5Hour and Usage7Day segments
- Interactive threshold editing (cycle through 40/50/60/70/80/90/95%)
- Color picker integration for warning/critical colors
- Dynamic field navigation based on segment type
- Real-time preview updates

Changes:
- segment_list.rs: Extended FieldSelection enum with:
  - WarningThreshold
  - CriticalThreshold
  - WarningColor
  - CriticalColor

- settings.rs: Conditional display of threshold fields
  - Show threshold fields only for usage segments
  - Extract and display current threshold values from options
  - Display warning/critical colors with proper formatting

- app.rs: Full editing support
  - Dynamic field count (11 for usage segments, 7 for others)
  - Navigation logic updated for threshold fields
  - Threshold cycling (Enter to cycle through common values)
  - Color picker opens for WarningColor/CriticalColor
  - apply_selected_color stores colors in segment options

Usage:
1. Open TUI: ccline -c
2. Navigate to Usage5Hour or Usage7Day segment
3. Use Up/Down to select threshold fields
4. Press Enter to cycle threshold values or open color picker
5. Press [S] to save configuration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Update TUI preview component to reflect the latest changes to usage segments:

Changes:
- Use Unicode arrow (→) instead of ASCII (->)
- Update 7-day format: "Oct 9:5am" instead of "Oct 9, 5am"
- Add get_threshold_color() method to apply threshold-based color overrides
- Update mock utilization values to demonstrate threshold states:
  - Usage5Hour: 65% (triggers warning color - yellow)
  - Usage7Day: 85% (triggers critical color - red)
- Update dynamic icons to match utilization levels

The preview now accurately shows threshold-based coloring in real-time,
allowing users to see how their threshold settings affect the display
before saving the configuration.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Update default threshold colors to use 16-color ANSI palette (c16)
instead of 256-color palette (c256) for better terminal compatibility
and consistency with the TUI display.

Changes:
- theme_default.rs: Changed warning_color from c256:226 to c16:11,
  critical_color from c256:196 to c16:9
- theme_gruvbox.rs: Same color updates for both usage segments
- theme_cometix.rs: Same color updates for both usage segments
- All themes: Updated usage_7day default icon/text color from c16:11
  (yellow) to c16:12 (light blue) for visual differentiation
- README.md: Updated documentation to show c16 defaults

Color mappings:
- Warning: c16:11 (Yellow) - equivalent to c256:226
- Critical: c16:9 (Light Red) - equivalent to c256:196

Benefits:
- Better compatibility with terminals that don't support 256 colors
- Matches TUI configurator display format (16:11, 16:9)
- More consistent with other segment color definitions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Add warning_bold and critical_bold options to usage segments, allowing text
to become bold when usage exceeds warning or critical thresholds. This provides
additional visual prominence for high usage states.

Features:
- New options: warning_bold (default: false), critical_bold (default: true)
- Automatic bold text when thresholds are exceeded
- Independent control for warning and critical states
- Works alongside threshold color changes

Default behavior:
- Default/Gruvbox themes: warning=normal, critical=bold
- Cometix theme: warning=bold, critical=bold (matches theme style)

Changes:
- usage_5hour.rs: Added should_be_bold() method to check bold options
  and apply text_bold_override to metadata
- usage_7day.rs: Same should_be_bold() logic for 7-day segment
- statusline.rs: Check for text_bold_override in metadata and apply
  instead of default text_bold style
- theme_*.rs: Added warning_bold and critical_bold options to all themes

Usage example:
```toml
[[segments]]
id = "usage_5hour"
[segments.options]
warning_bold = true   # Make text bold at 60% usage
critical_bold = true  # Make text bold at 80% usage
```

Result: Critical usage now displays in bold red text for maximum visibility!

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…ator

Add full TUI support for configuring warning_bold and critical_bold options in Usage (5-hour) and Usage (7-day) segments.

Changes:
- Add WarningBold and CriticalBold to FieldSelection enum
- Display bold toggle fields in settings panel with [✓]/[ ] indicators
- Add color swatches (██) for warning/critical color fields
- Update navigation to handle 13 fields for usage segments (was 11)
- Add Enter key handlers to toggle bold options
- Show status messages when bold settings are changed
- Update preview in real-time when bold options are toggled

Users can now press Enter on "Warning Bold" or "Critical Bold" fields to toggle them on/off, making it easy to configure threshold-based bold text styling without manual TOML editing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Address code review comments by introducing shared helper functions and
clarifying utilization value format:

**New shared utilities (color_utils.rs):**
- serialize_ansi_color_to_json(): Eliminates duplicated color serialization
- c16_to_ratatui_color(): Centralizes 16-color ANSI to ratatui::Color mapping
- ansi_color_to_ratatui(): Handles all color formats (c16, c256, RGB)

**Refactored files:**
- usage_5hour.rs: Use serialize_ansi_color_to_json(), clarify utilization format
- usage_7day.rs: Use serialize_ansi_color_to_json(), clarify utilization format
- settings.rs: Replace 6 duplicated color mappings with color_utils helpers
- app.rs: Use serialize_ansi_color_to_json() for warning/critical colors
- mod.rs: Export new color_utils module

**Documentation improvements:**
- Added comments clarifying utilization values are percentages (0-100)
- Added comments explaining division by 100 converts to normalized values (0-1)
- This addresses reviewer questions about get_circle_icon expectations

**Code quality improvements:**
- Reduced duplication: ~100 lines of repeated color mapping code eliminated
- Single source of truth: Color conversion logic now centralized
- Maintainability: Future color format changes only require updating one place
- Consistency: All color conversions now use the same helper functions

Addresses review comments from PR code review.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Add missing warning/critical threshold configurations to usage 5-hour and
7-day segments in minimal, nord, and all powerline themes. These themes were
missing the threshold options that were already present in default, gruvbox,
and cometix themes.

Adds the following threshold options to usage segments:
- warning_threshold: 60% (triggers yellow color)
- critical_threshold: 80% (triggers red color with bold text)
- warning_color: yellow (ANSI c16: 11)
- critical_color: red (ANSI c16: 9)
- warning_bold: false
- critical_bold: true

This ensures all themes have consistent threshold-based visual feedback for
usage tracking segments.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Extend threshold-based color and bold text support to the context window segment,
matching the implementation from usage segments (5-hour/7-day). This provides
visual feedback when context usage exceeds configurable warning (60%) and critical
(80%) thresholds.

**Implementation:**
- context_window.rs: Add get_color_for_utilization() and should_be_bold() methods
  - Uses color_utils::serialize_ansi_color_to_json() from PR Haleclipse#41
  - Checks utilization against warning_threshold (default 60%) and critical_threshold (default 80%)
  - Returns appropriate color/bold overrides based on threshold levels
- app.rs, settings.rs: Include ContextWindow in threshold segment checks for TUI
  - Enables threshold configuration UI for context window segment
  - Adds 6 threshold fields (thresholds, colors, bold flags) to segment settings
- All 9 themes: Add threshold options to context_window_segment() functions
  - warning_threshold: 60%, critical_threshold: 80%
  - warning_color: c16=11 (yellow), critical_color: c16=9 (red)
  - Cometix/Gruvbox: Both thresholds use bold (warning_bold/critical_bold: true)
  - Default/Minimal/Nord/Powerline themes: Only critical uses bold

**Dependencies:**
- Requires color_utils module from PR Haleclipse#41 (enhanced-usage-segments)
- This PR should not be merged until PR Haleclipse#41 is merged

**Default behavior:**
- Warning: 60% utilization → yellow text, normal weight (bold in Cometix/Gruvbox)
- Critical: 80% utilization → red text, bold weight
- Below warning: Uses default segment colors

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@sourcery-ai
Copy link

sourcery-ai bot commented Oct 10, 2025

Reviewer's Guide

This PR adds warning/critical threshold support across the context window and usage segments, integrating core evaluation methods, TUI controls, theme presets, new segment modules, shared color utilities, and updates to statusline, preview, configuration, and documentation.

Sequence diagram for TUI threshold configuration and preview update

sequenceDiagram
    actor User
    participant TUI_SettingsPanel
    participant App
    participant Config
    participant PreviewComponent
    User->>TUI_SettingsPanel: Select Usage5Hour/Usage7Day/ContextWindow segment
    TUI_SettingsPanel->>App: User changes threshold field (e.g., warning_threshold)
    App->>Config: Update segment.options with new threshold value
    App->>PreviewComponent: update_preview(&config)
    PreviewComponent->>Config: Read updated segment threshold options
    PreviewComponent->>PreviewComponent: get_threshold_color() for utilization
    PreviewComponent->>TUI_SettingsPanel: Display preview with color/bold override
Loading

Class diagram for new and updated usage segments with threshold logic

classDiagram
    class UsageSegment {
        +five_hour_utilization: f64
        +seven_day_utilization: f64
        +five_hour_resets_at: Option<String>
        +seven_day_resets_at: Option<String>
        +cached_at: String
        +get_circle_icon(utilization: f64) String
        +format_5hour_reset_time(reset_time_str: Option<&str>) String
        +format_7day_reset_time(reset_time_str: Option<&str>) String
        +load_usage_cache() Option<ApiUsageCache>
    }
    class Usage5HourSegment {
        +collect(input: &InputData) Option<SegmentData>
        +get_color_for_utilization(utilization: f64) Option<AnsiColor>
        +should_be_bold(utilization: f64) Option<bool>
    }
    class Usage7DaySegment {
        +collect(input: &InputData) Option<SegmentData>
        +get_color_for_utilization(utilization: f64) Option<AnsiColor>
        +should_be_bold(utilization: f64) Option<bool>
    }
    Usage5HourSegment ..> UsageSegment : uses cache and helpers
    Usage7DaySegment ..> UsageSegment : uses cache and helpers
    class ContextWindowSegment {
        +get_color_for_utilization(utilization: f64) Option<AnsiColor>
        +should_be_bold(utilization: f64) Option<bool>
        +collect(input: &InputData) Option<SegmentData>
    }
    class color_utils {
        +serialize_ansi_color_to_json(color: &AnsiColor) String
        +c16_to_ratatui_color(c16: u8) Color
        +ansi_color_to_ratatui(color: &AnsiColor) Color
    }
    Usage5HourSegment ..> color_utils : uses
    Usage7DaySegment ..> color_utils : uses
    ContextWindowSegment ..> color_utils : uses
Loading

File-Level Changes

Change Details Files
Threshold logic in context window segment
  • Add get_color_for_utilization and should_be_bold methods
  • Inject text_color_override and text_bold_override in collect() via color_utils
src/core/segments/context_window.rs
TUI integration for threshold settings
  • Replace manual color mapping with ansi_color_to_ratatui helper
  • Add threshold fields and bold flags in settings component
  • Update app.rs navigation and event handlers for threshold, color and bold toggles
  • Introduce new FieldSelection variants for thresholds
src/ui/components/settings.rs
src/ui/app.rs
src/ui/components/segment_list.rs
Theme presets and built-in themes updated
  • Extend context_window_segment options with threshold configs
  • Add usage_5hour_segment and usage_7day_segment to all themes
  • Update presets to include new usage segments
src/ui/themes/theme_*.rs
src/ui/themes/presets.rs
New Usage5Hour and Usage7Day segment modules
  • Implement segments with shared cache load and threshold evaluation
  • Expose time formatting and cache loader helpers in usage.rs
src/core/segments/usage_5hour.rs
src/core/segments/usage_7day.rs
src/core/segments/usage.rs
Color utilities module
  • Add serialize_ansi_color_to_json helper
  • Add ansi_color_to_ratatui and c16_to_ratatui_color functions
src/core/segments/color_utils.rs
Statusline and preview apply threshold overrides
  • Parse and apply text_color_override/text_bold_override in statusline
  • Add get_threshold_color and mock preview entries for new usage segments
src/core/statusline.rs
src/ui/components/preview.rs
Configuration and documentation updates
  • Extend SegmentId enum and bump crate version
  • Update README with usage segment and threshold docs
  • Add 1.0.9 entry in CHANGELOG
Cargo.toml
src/config/types.rs
README.md
CHANGELOG.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes - here's some feedback:

  • There’s significant duplication in the threshold logic across ContextWindowSegment, Usage5HourSegment, and Usage7DaySegment—consider extracting a shared helper or trait for get_color_for_utilization and should_be_bold to DRY up the code.
  • You’re calling Config::load() on every threshold check, which could be expensive; think about caching the loaded config or injecting it into the segments so you don’t reload from disk on each call.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- There’s significant duplication in the threshold logic across ContextWindowSegment, Usage5HourSegment, and Usage7DaySegment—consider extracting a shared helper or trait for get_color_for_utilization and should_be_bold to DRY up the code.
- You’re calling Config::load() on every threshold check, which could be expensive; think about caching the loaded config or injecting it into the segments so you don’t reload from disk on each call.

## Individual Comments

### Comment 1
<location> `src/core/segments/usage.rs:95` </location>
<code_context>
+    }
+
+    /// Format 7-day reset time as "Oct 9, 5am"
+    pub fn format_7day_reset_time(reset_time_str: Option<&str>) -> String {
+        if let Some(time_str) = reset_time_str {
+            if let Ok(dt) = DateTime::parse_from_rfc3339(time_str) {
</code_context>

<issue_to_address>
**suggestion:** Date formatting for 7-day reset time may produce ambiguous output.

Consider replacing the colon with a comma to avoid confusion, e.g., "Oct 9, 5am".

Suggested implementation:

```rust
                let hour = local_dt.hour();
                let (hour_12, period) = if hour == 0 {
                    (12, "am")
                } else if hour < 12 {
                    (hour, "am")

```

```rust
                // Format as "Oct 9, 5am"
                return format!(
                    "{} {}, {}{}",
                    local_dt.format("%b"),
                    local_dt.day(),
                    hour_12,
                    period
                );

```
</issue_to_address>

### Comment 2
<location> `src/core/segments/context_window.rs:22` </location>
<code_context>
         model_config.get_context_limit(model_id)
     }
+
+    fn get_color_for_utilization(&self, utilization: f64) -> Option<AnsiColor> {
+        // Load config to get threshold settings
+        let config = Config::load().ok()?;
</code_context>

<issue_to_address>
**suggestion:** get_color_for_utilization and should_be_bold duplicate logic found in usage_5hour and usage_7day.

Refactor the threshold logic into a shared helper to eliminate duplication and enhance maintainability.

Suggested implementation:

```rust
    /// Helper to get warning and critical thresholds for a segment
    fn get_thresholds_for_segment(segment_id: SegmentId) -> Option<(f64, f64)> {
        let config = Config::load().ok()?;
        let segment_config = config.segments.iter().find(|s| s.id == segment_id)?;
        let warning_threshold = segment_config
            .options
            .get("warning_threshold")
            .and_then(|v| v.as_u64())
            .unwrap_or(60) as f64;
        let critical_threshold = segment_config
            .options
            .get("critical_threshold")
            .and_then(|v| v.as_u64())
            .unwrap_or(80) as f64;
        Some((warning_threshold, critical_threshold))
    }

    fn get_color_for_utilization(&self, utilization: f64) -> Option<AnsiColor> {
        let (warning_threshold, critical_threshold) = Self::get_thresholds_for_segment(SegmentId::ContextWindow)?;

```

```rust
        if utilization >= critical_threshold {
            Some(AnsiColor::Red)
        } else if utilization >= warning_threshold {
            Some(AnsiColor::Yellow)
        } else {
            Some(AnsiColor::Green)
        }
    }

```

```rust
    fn should_be_bold(&self, utilization: f64) -> bool {
        let (_, critical_threshold) = Self::get_thresholds_for_segment(SegmentId::ContextWindow)?;
        utilization >= critical_threshold
    }

```

You will also need to refactor the threshold logic in `usage_5hour` and `usage_7day` to use the new `get_thresholds_for_segment` helper. Replace any duplicated config/threshold extraction with calls to this helper, passing the appropriate `SegmentId`.
</issue_to_address>

### Comment 3
<location> `src/ui/app.rs:471-472` </location>
<code_context>
+                    .map(|s| matches!(s.id, crate::config::SegmentId::Usage5Hour | crate::config::SegmentId::Usage7Day | crate::config::SegmentId::ContextWindow))
+                    .unwrap_or(false);
+
+                let field_count = if is_usage_segment {
+                    13 // Enabled, Icon, IconColor, TextColor, BackgroundColor, TextStyle, WarningThreshold, CriticalThreshold, WarningColor, CriticalColor, WarningBold, CriticalBold, Options
+                } else {
+                    7 // Enabled, Icon, IconColor, TextColor, BackgroundColor, TextStyle, Options
</code_context>

<issue_to_address>
**suggestion:** Field count for usage segments is hardcoded; consider using a constant or deriving from enum.

Using a hardcoded value increases the risk of errors if the enum changes. Please use a constant or derive the count directly from the FieldSelection enum to ensure consistency.

Suggested implementation:

```rust
                // Use constants for field counts to avoid hardcoding
                const USAGE_SEGMENT_FIELD_COUNT: usize = {
                    // If FieldSelection is an enum with EnumIter, filter for usage fields
                    use crate::config::FieldSelection;
                    FieldSelection::iter()
                        .filter(|f| matches!(
                            f,
                            FieldSelection::Enabled
                                | FieldSelection::Icon
                                | FieldSelection::IconColor
                                | FieldSelection::TextColor
                                | FieldSelection::BackgroundColor
                                | FieldSelection::TextStyle
                                | FieldSelection::WarningThreshold
                                | FieldSelection::CriticalThreshold
                                | FieldSelection::WarningColor
                                | FieldSelection::CriticalColor
                                | FieldSelection::WarningBold
                                | FieldSelection::CriticalBold
                                | FieldSelection::Options
                        ))
                        .count()
                };

                const DEFAULT_SEGMENT_FIELD_COUNT: usize = {
                    use crate::config::FieldSelection;
                    FieldSelection::iter()
                        .filter(|f| matches!(
                            f,
                            FieldSelection::Enabled
                                | FieldSelection::Icon
                                | FieldSelection::IconColor
                                | FieldSelection::TextColor
                                | FieldSelection::BackgroundColor
                                | FieldSelection::TextStyle
                                | FieldSelection::Options
                        ))
                        .count()
                };

                let field_count = if is_usage_segment {
                    USAGE_SEGMENT_FIELD_COUNT
                } else {
                    DEFAULT_SEGMENT_FIELD_COUNT
                };

```

1. This change assumes that `FieldSelection` is an enum and derives `EnumIter` from the `strum` crate. If not, you will need to add `#[derive(EnumIter)]` to the enum and add `strum = "0.24"` (or similar) to your Cargo.toml.
2. You may need to import `strum::IntoEnumIterator` and `crate::config::FieldSelection` at the top of the file.
3. If you do not want to use `strum`, you can define the constants manually, but this will not automatically update if the enum changes.
</issue_to_address>

### Comment 4
<location> `src/ui/app.rs:719-464` </location>
<code_context>
                 FieldSelection::IconColor => segment.colors.icon = Some(color),
                 FieldSelection::TextColor => segment.colors.text = Some(color),
                 FieldSelection::BackgroundColor => segment.colors.background = Some(color),
+                FieldSelection::WarningColor => {
+                    // Store warning color in options using shared helper
+                    let color_json: serde_json::Value = serde_json::from_str(&color_utils::serialize_ansi_color_to_json(&color)).unwrap();
+                    segment.options.insert("warning_color".to_string(), color_json);
+                }
+                FieldSelection::CriticalColor => {
+                    // Store critical color in options using shared helper
</code_context>

<issue_to_address>
**issue (bug_risk):** Color picker serialization/deserialization may panic if color_utils returns invalid JSON.

Using unwrap here may cause a panic if serialize_ansi_color_to_json ever returns invalid JSON. Consider handling the error or using from_value for safer deserialization.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

This commit addresses all feedback from the PR code review by introducing
shared utilities, config caching, and improving code maintainability.

**Changes:**

1. **New threshold_utils module (addresses duplication concerns)**
   - Created src/core/segments/threshold_utils.rs
   - Extracts shared threshold logic from context_window, usage_5hour, usage_7day
   - Implements config caching using once_cell to avoid repeated disk I/O
   - Provides centralized functions:
     * get_thresholds_for_segment(): Extract warning/critical thresholds
     * get_color_for_utilization(): Determine color based on utilization
     * should_be_bold(): Determine bold text based on utilization

2. **Refactored segments to use shared utilities**
   - context_window.rs: Removed duplicated get_color_for_utilization/should_be_bold
   - usage_5hour.rs: Removed duplicated threshold methods
   - usage_7day.rs: Removed duplicated threshold methods
   - All segments now call threshold_utils functions with SegmentId parameter
   - Reduced ~200 lines of duplicated code

3. **Fixed date formatting (Comment 1)**
   - usage.rs: Changed format_7day_reset_time output from "Oct 9:5am" to "Oct 9, 5am"
   - Added comma for better readability and consistency with comment suggestion

4. **Added field count constants (Comment 3)**
   - app.rs: Defined DEFAULT_SEGMENT_FIELD_COUNT (7) and THRESHOLD_SEGMENT_FIELD_COUNT (13)
   - Replaced inline hardcoded values with named constants
   - Improved maintainability and reduced error risk

5. **Fixed potential panic in color picker (Comment 4)**
   - app.rs: Replaced unwrap() with proper error handling using if-let Ok()
   - Prevents panic if serialize_ansi_color_to_json returns unexpected format
   - Safely handles JSON parsing failures for WarningColor and CriticalColor

**Dependencies:**
- Added once_cell = "1.19" to Cargo.toml for config caching

**Testing:**
- ✅ Compiles successfully with cargo build --release
- ✅ All threshold functionality preserved with shared utilities
- ✅ Config caching reduces disk I/O for threshold checks

**Impact:**
- Eliminated ~200 lines of duplicated code
- Improved performance with config caching
- Better maintainability with centralized threshold logic
- Reduced risk of inconsistencies across segments

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@Haleclipse Haleclipse force-pushed the master branch 3 times, most recently from 1afab9d to f36d76a Compare January 25, 2026 20:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant