Skip to content

Live monitoring dashboard box layout misalignment in various terminal widths #172

@Sixeight

Description

@Sixeight

When using the ccusage blocks --live command to display the real-time token usage monitoring dashboard, the box borders become misaligned in certain terminal widths. The right border (│) appears to be offset or
"jumps" to incorrect positions, breaking the visual layout of the dashboard.

Steps to Reproduce

  1. Install ccusage: npm i -g ccusage
  2. Run the live monitoring mode: ccusage blocks --live
  3. Resize your terminal window to different widths
  4. Observe that the right border of the box becomes misaligned

Expected Behavior

The dashboard should display a perfectly aligned box with all borders (┌─┐│└┘) forming a proper rectangle, regardless of the terminal width. All lines should have consistent width and the right border should align
vertically.

Actual Behavior

The right border (│) characters are not vertically aligned. In some cases:

  • The border appears inside the expected position (box content is truncated)
  • The border appears outside the expected position (box extends beyond intended width)
  • Different rows have different widths, causing a "jagged" appearance

Screenshots
Image

Here are examples of the misalignment issue:

  1. Border appearing too far to the right:
    • The box extends beyond its intended boundaries
    • Some rows are longer than others
  2. Border appearing too far to the left:
    • Content appears truncated
    • The box doesn't fill the intended width properly

Technical Details

Environment:

  • OS: macOS Darwin 24.5.0
  • Terminal: Various (tested on multiple terminal emulators)
  • Node.js version: v24.2.0
  • ccusage version: 15.2.0

Root Cause Analysis:

The issue appears to stem from inconsistent width calculations across different parts of the rendering logic:

  1. Mixed padding calculations: Different lines use different formulas for padding:
  • Some use boxWidth - 2
  • Others use boxWidth - 3
  • String width calculations with stringWidth() don't always match actual terminal rendering
  1. Inconsistent line structure: The code mixes different patterns:
  • │ content │ (with spaces inside borders)
  • │content│ (without spaces)
  • This leads to different width calculations for different rows
  1. ANSI escape sequences: The stringWidth function is used to calculate visible width excluding ANSI codes, but the padding calculations don't consistently account for the actual structure of each line.

Attempted Solutions

Several approaches were tried to fix this issue:

  1. Unified padding calculation: Attempted to use boxWidth - 2 consistently
  2. Helper function approach: Created a padLine function to centralize width calculations
  3. Content width abstraction: Tried to separate content width from box width

However, these solutions haven't fully resolved the alignment issues across all terminal widths and content combinations.

Additional Context

The issue is particularly noticeable when:

  • The terminal width changes
  • Different types of content (progress bars, text, formatted numbers) are displayed
  • The box contains Unicode characters (emojis, special symbols)

This is a visual/cosmetic issue that doesn't affect the functionality of the tool, but it does impact the user experience and professional appearance of the live monitoring feature.

Possible Solution Directions

  1. Standardize box drawing approach: Use a consistent pattern for all lines
  2. Terminal width detection: Ensure accurate terminal width detection
  3. Box drawing library: Consider using a specialized library for terminal box drawing
  4. Character width handling: Better handle multi-byte characters and emojis
  5. Testing framework: Add visual regression tests for different terminal widths

Would appreciate any insights or suggestions on how to properly handle terminal box alignment across different environments and terminal widths.

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions