Skip to content

fix(cli): align session tables with CJK content via display-width padding#44211

Open
AIalliAI wants to merge 1 commit into
NousResearch:mainfrom
AIalliAI:fix/44199-cjk-session-table-alignment
Open

fix(cli): align session tables with CJK content via display-width padding#44211
AIalliAI wants to merge 1 commit into
NousResearch:mainfrom
AIalliAI:fix/44199-cjk-session-table-alignment

Conversation

@AIalliAI

Copy link
Copy Markdown
Contributor

Fixes #44199

Problem

The /resume inline list (HermesCLI._show_recent_sessions, cli.py) and the hermes sessions list table (cmd_sessions, hermes_cli/main.py) pad cells with str.format width specs ({var:<32}) and truncate with str slices ([:38]). Both count characters, but CJK characters occupy two terminal columns, so any title or preview containing them shifts every column to its right:

  #   Title                            Preview                                  Last Active   ID
  ─── ──────────────────────────────── ──────────────────────────────────────── ───────────── ────────────────────────
  2   整理论文和更新README #4                 我更新了paper/和 …   6d ago        20260604_195221_254cc9

Fix

Rather than switching these renderers to rich.table.Table, this adds three small display-width helpers to hermes_cli/main.py_disp_width / _clip_to_width / _pad_to_width — using the same wcwidth-based approach (including the clamp-negative-to-zero convention) that agent/markdown_tables.py already uses for exactly this problem. Both renderers now truncate and pad by terminal columns. _clip_to_width never splits a double-width character across the column boundary.

This keeps the diff minimal and the output byte-identical for pure-ASCII rows, so nothing depending on the current format changes. wcwidth is already imported unconditionally by agent/markdown_tables.py and is guaranteed present transitively via the pinned prompt_toolkit.

After:

  #   Title                            Preview                                  Last Active   ID
  ─── ──────────────────────────────── ──────────────────────────────────────── ───────────── ────────────────────────
  1   整理论文和更新README #4          我更新了paper/和 README,整理了所有章    6d ago        20260604_195221_254cc9
  2   Refactor session storage         moved sqlite schema into hermes_state    ?             20260603_101512_aa11bb

Notes on scope

  • Titles in the /resume table are padded but deliberately not clipped: /resume fails on title match because display truncates titles to 30 chars #14082 made long titles render in full there (enforced by test_resume_list_shows_full_long_titles), so an over-long title still trades alignment for visibility, exactly as on main. Only the preview is clipped — now by columns instead of characters.
  • cmd_sessions keeps its existing [:30] title truncation semantics, just measured in columns.
  • The issue's suggestion to move Last Active/ID to the left is a layout change beyond the alignment bug, so it's left out of this fix.

Tests

  • tests/hermes_cli/test_session_table_width.py (new): unit coverage for the three helpers — CJK widths, never splitting a double-width char at the boundary, negative-wcswidth clamping, ASCII equivalence with str.ljust.
  • tests/cli/test_cli_resume_command.py: new test asserting the ID column starts at the same display column for a CJK row and an ASCII row.
  • Full tests/cli/ suite passes (the one failure, test_resume_quiet_stderr.py::test_session_not_found_goes_to_stdout_in_full_mode, is a pre-existing test-ordering flake that fails identically on pristine origin/main when the whole directory runs together, and passes in isolation both there and on this branch).

🤖 Generated with Claude Code

…ding

The /resume inline list (HermesCLI._show_recent_sessions) and the
`hermes sessions list` table (cmd_sessions) pad cells with str.format
width specs and truncate with str slices, both of which count
characters rather than terminal columns. CJK characters are
double-width, so any title or preview containing them shifted every
column to its right.

Add _disp_width/_clip_to_width/_pad_to_width helpers to
hermes_cli/main.py — the same wcwidth-based approach (and -1-clamping
convention) agent/markdown_tables.py already uses for this problem —
and use them in both renderers. wcwidth is already a transitive
guarantee via prompt_toolkit.

Output is byte-identical for pure-ASCII rows, and titles in the
/resume table still render unclipped (NousResearch#14082); only the preview is
clipped there, by columns instead of characters.

Fixes NousResearch#44199

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@alt-glitch alt-glitch added type/bug Something isn't working comp/cli CLI entry point, hermes_cli/, setup wizard P3 Low — cosmetic, nice to have labels Jun 11, 2026
@AIalliAI

Copy link
Copy Markdown
Contributor Author

Requesting maintainer review — this is ready to land from my side. Standalone fork CI is pending first-run approval here; the rollup branch in #44061 carrying this session's batch is fully green on upstream CI (all test shards, typecheck, e2e).

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

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard P3 Low — cosmetic, nice to have type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(cli): CJK characters misaligned in /resume and sessions list tables

2 participants