Skip to content

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

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.

Activity

  1. ryoppippi commented on Jun 23, 2025

    @ryoppippi
    Member

    I tested and found

    • it doesn't work with some fonts.
    • in my environment, wezterm causes a little layout mismatch
    • ghostty is perfect

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

    Is it AI generated? we don't know it.

  2. Sixeight commented on Jun 23, 2025

    @Sixeight
    Author

    Ghostty displays correctly, but zellij seems to have layout issues. tmux works fine.

    In my environment (with any Font)

    • OK:
      • Ghostty
      • iTerm2
      • Warp
      • (terminal multiplexer) tmux
    • NG:
      • Terminal.app
      • Wezterm
      • (terminal multiplexer) zellij

    Is it AI generated? We don't know.

    Sorry. I had the AI create this issue.

  3. ryoppippi commented on Jun 25, 2025

    @ryoppippi
    Member

    Thanks for your investigation
    Hmm yeah we need to find how

  4. AsPulse commented on Jun 26, 2025

    @AsPulse
    Contributor

    The problem seems to be whether the emoji next to “SESSION” and “Models” are full-width or half-width.

    OK (full-width emoji, Warp)
    Image

    NG (half-width emoji, Zellij over Ghostty)
    Image

    For comparison, I have highlighted one half-width bit under the clock emoji to the left of SESSION.

    This can be seen from the fact that the beginning of “SESSION” and “USAGE” may or may not be aligned.

    Forcing the cursor to skip to a position 2 bytes after the emoji is drawn should solve this problem.

  5. AsPulse commented on Jun 26, 2025

    @AsPulse
    Contributor

    If you don't mind, please assign me to this Issue and I will implement it and send out a PR!
    (I am just having trouble with this issue myself)

  6. ryoppippi commented on Jun 28, 2025

    @ryoppippi
    Member

    Thank you @AsPulse ! Go ahead!!!!

  7. AsPulse commented on Jul 20, 2025

    @AsPulse
    Contributor

    I had a free hand and tried to get to it, but the emoji width issue that was the biggest problem with this issue seems to have been resolved in the latest main branch.
    I will try to resolve the other issues that are causing the display to be corrupted.

    Sorry for the delay in responding......!!!
    It was still occurring in some environments. I will continue to work on a fix.

  8. ryoppippi commented on Jul 22, 2025

    @ryoppippi
    Member

    thanks!! if you are fine close this issue

  9. AsPulse commented on Jul 23, 2025

    @AsPulse
    Contributor

    Thanks for the merge, but this issue is still not completely resolved.
    It may take a little more time to determine the cause, but I will eventually issue another PR,
    so I would appreciate it if you could leave the issue open.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions