Skip to content

Commit c9b5bea

Browse files
committed
fix(plugin): make Tiny Actor Grid layout display-width-safe for CJK/ANSI (#1304)
Replace ljust() with pad_to_display_width() in layout_grid() so multi-column rows stay visually aligned with CJK labels, emoji, and ANSI-colored content.
1 parent f0b1879 commit c9b5bea

2 files changed

Lines changed: 63 additions & 1 deletion

File tree

packages/claude-code-plugin/hooks/lib/tiny_actor_grid.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
from itertools import zip_longest
99

10+
from buddy_renderer import display_width, pad_to_display_width
11+
1012

1113
def layout_grid(
1214
cards: list[list[str]],
@@ -55,7 +57,7 @@ def layout_grid(
5557
padded_cards.append(padded)
5658

5759
for line_parts in zip_longest(*padded_cards, fillvalue=" " * card_width):
58-
parts = [part.ljust(card_width) for part in line_parts]
60+
parts = [pad_to_display_width(part, card_width) for part in line_parts]
5961
# Pad row to full width when fewer cards than max_columns
6062
while len(parts) < max_columns:
6163
parts.append(" " * card_width)

packages/claude-code-plugin/tests/test_tiny_actor_grid.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
if _lib_dir not in sys.path:
1111
sys.path.insert(0, _lib_dir)
1212

13+
from buddy_renderer import display_width
1314
from tiny_actor_grid import layout_grid
1415

1516
# ---------------------------------------------------------------------------
@@ -79,6 +80,65 @@ def test_all_lines_consistent_width(self):
7980
widths = {len(line) for line in lines}
8081
assert len(widths) == 1, f"Expected uniform width, got {widths}"
8182

83+
def test_cjk_labels_consistent_display_width(self):
84+
"""Cards with CJK text must produce uniform display width across rows."""
85+
from buddy_renderer import pad_to_display_width
86+
87+
def _cjk_card() -> list[str]:
88+
return [
89+
pad_to_display_width("한국어", _CARD_WIDTH),
90+
pad_to_display_width("테스트", _CARD_WIDTH),
91+
pad_to_display_width("라벨", _CARD_WIDTH),
92+
]
93+
94+
cards = [_cjk_card(), _make_card(label="A"), _cjk_card()]
95+
lines = layout_grid(cards, available_width=80, card_width=_CARD_WIDTH, gap=2)
96+
widths = {display_width(line) for line in lines}
97+
assert len(widths) == 1, f"CJK grid display widths not uniform: {widths}"
98+
99+
def test_ansi_colored_text_consistent_display_width(self):
100+
"""Cards with ANSI escape codes must produce uniform display width."""
101+
from buddy_renderer import pad_to_display_width
102+
103+
RED = "\033[31m"
104+
RESET = "\033[0m"
105+
106+
def _ansi_card() -> list[str]:
107+
return [
108+
pad_to_display_width(f"{RED}colored{RESET}", _CARD_WIDTH),
109+
pad_to_display_width(f"{RED}face{RESET}", _CARD_WIDTH),
110+
pad_to_display_width(f"{RED}text{RESET}", _CARD_WIDTH),
111+
]
112+
113+
cards = [_ansi_card(), _make_card(label="B"), _ansi_card()]
114+
lines = layout_grid(cards, available_width=80, card_width=_CARD_WIDTH, gap=2)
115+
widths = {display_width(line) for line in lines}
116+
assert len(widths) == 1, f"ANSI grid display widths not uniform: {widths}"
117+
118+
def test_mixed_cjk_ansi_ascii_consistent(self):
119+
"""Mixed CJK, ANSI, and ASCII cards in one grid stay aligned."""
120+
from buddy_renderer import pad_to_display_width
121+
122+
GREEN = "\033[32m"
123+
RESET = "\033[0m"
124+
125+
cjk_card = [
126+
pad_to_display_width("보안전문가", _CARD_WIDTH),
127+
pad_to_display_width("분석중", _CARD_WIDTH),
128+
pad_to_display_width("완료", _CARD_WIDTH),
129+
]
130+
ansi_card = [
131+
pad_to_display_width(f"{GREEN}status{RESET}", _CARD_WIDTH),
132+
pad_to_display_width(f"{GREEN}ok{RESET}", _CARD_WIDTH),
133+
pad_to_display_width(f"{GREEN}done{RESET}", _CARD_WIDTH),
134+
]
135+
ascii_card = _make_card(label="Z")
136+
137+
cards = [cjk_card, ansi_card, ascii_card]
138+
lines = layout_grid(cards, available_width=80, card_width=_CARD_WIDTH, gap=2)
139+
widths = {display_width(line) for line in lines}
140+
assert len(widths) == 1, f"Mixed grid display widths not uniform: {widths}"
141+
82142

83143
# ---------------------------------------------------------------------------
84144
# Edge cases

0 commit comments

Comments
 (0)