hermes-agent/tests/cli
Teknium 1d00716754
fix(cli,tui): align CJK / wide-char markdown tables (#23863)
CJK and emoji glyphs render as two terminal cells but JS String#length
and the model's own padding count them as one, so any markdown table
with Chinese / Japanese / Korean cells drifts right per row when a
real terminal renders it. Both surfaces fix this with a display-cell
width measurement (wcswidth on the Python side, stringWidth on the
TUI side).

Changes:
- agent/markdown_tables.py: new helper. realign_markdown_tables(text)
  detects markdown table blocks (header + |---| divider) and
  rewrites the row padding using wcwidth.wcswidth so every pipe and
  dash lines up across rows. No-op on text without tables.
- cli.py: hook the helper into _render_final_assistant_content for
  strip / render modes (raw passes through untouched), and into the
  streaming line emitter so live token-by-token rendering also
  produces aligned tables. A small two-buffer state machine in
  _emit_stream_text holds table rows until the block ends, then
  flushes them through the realigner so all rows pad to a single
  per-column width.
- ui-tui/src/components/markdown.tsx: renderTable now uses
  stringWidth (Bun.stringWidth fast path + East-Asian-width-aware
  fallback, already memoised in @hermes/ink) instead of UTF-16
  String#length for both column-width measurement and per-cell
  padding. Drops the comment that documented the bug as a deliberate
  limitation.

Validation:
- New tests/agent/test_markdown_tables.py (11): every rebuilt block
  shares pipe column offsets across rows for pure CJK, mixed
  CJK+emoji, ragged-row, and multi-table inputs.
- Updated tests/cli/test_cli_markdown_rendering.py: the existing
  strip-mode test asserted exact whitespace; rewritten to assert the
  alignment contract (cell content survives + every rendered row
  shares pipe offsets).
- New ui-tui markdown.test.ts case (1): rendered column-2 start
  offset is identical for the header + every body row, including
  the CJK row that drifted before the fix.
- Live: hermes chat -q with the user-reported screenshot prompt now
  produces a perfectly aligned table on the wire (header, divider,
  4 body rows including '通义千问', all pipes at identical columns).
2026-05-11 11:13:06 -07:00
..
__init__.py
test_branch_command.py feat(memory): notify providers on mid-process session_id rotation (#17409) 2026-04-29 04:57:22 -07:00
test_busy_input_mode_command.py feat(busy): add 'steer' as a third display.busy_input_mode option (#16279) 2026-04-26 18:21:29 -07:00
test_cli_approval_ui.py feat(openrouter): wire Pareto Code router with min_coding_score knob (#22838) 2026-05-09 14:47:00 -07:00
test_cli_background_tui_refresh.py
test_cli_bracketed_paste_sanitizer.py fix(cli): strip leaked bracketed-paste wrappers 2026-04-26 21:47:40 -07:00
test_cli_browser_connect.py fix(browser): address Copilot review on /browser connect 2026-04-28 22:11:10 -07:00
test_cli_context_warning.py
test_cli_copy_command.py
test_cli_extension_hooks.py
test_cli_external_editor.py
test_cli_file_drop.py fix(cli): catch OSError in _resolve_attachment_path to prevent ENAMETOOLONG dropping long slash commands 2026-05-06 06:34:48 -07:00
test_cli_force_redraw.py fix(cli): recover classic CLI output after resize 2026-05-06 04:20:54 -07:00
test_cli_goal_interrupt.py revert: roll back /goal checklist + /subgoal feature stack (#23813) 2026-05-11 07:06:27 -07:00
test_cli_image_command.py
test_cli_init.py fix(cli): make Ctrl+Enter insert newline on WSL/SSH/Windows Terminal (#22777) 2026-05-09 12:48:14 -07:00
test_cli_interrupt_subagent.py
test_cli_loading_indicator.py fix: clean up defensive shims and finish CI stabilization from #17660 (#17801) 2026-04-29 23:53:17 -07:00
test_cli_markdown_rendering.py fix(cli,tui): align CJK / wide-char markdown tables (#23863) 2026-05-11 11:13:06 -07:00
test_cli_mcp_config_watch.py
test_cli_new_session.py feat: confirm prompt for destructive slash commands (#4069) (#22687) 2026-05-09 11:04:46 -07:00
test_cli_prefix_matching.py
test_cli_preloaded_skills.py
test_cli_provider_resolution.py
test_cli_reload_skills.py refactor(reload-skills): queue note for next turn, drop cache invalidation + agent tool 2026-04-29 21:07:47 -07:00
test_cli_retry.py
test_cli_save_config_value.py fix(cli): preserve config comments on setting writes 2026-05-09 17:55:12 -07:00
test_cli_secret_capture.py
test_cli_shift_enter_newline.py feat(cli): recognise Shift+Enter as a newline key 2026-05-08 16:26:51 -07:00
test_cli_shutdown_memory_messages.py fix(cli): pass session messages to shutdown_memory_provider (#15165 sibling) 2026-04-27 06:41:16 -07:00
test_cli_skin_integration.py fix(tui): restore macOS copy behavior and theme polish (#17131) 2026-04-28 18:47:14 -05:00
test_cli_status_bar.py refactor: replace 'cmp' text with 🗜️ emoji in status bar 2026-05-07 05:27:45 -07:00
test_cli_status_command.py
test_cli_steer_busy_path.py fix(cli): dispatch /steer inline while agent is running (#13354) 2026-04-20 23:05:38 -07:00
test_cli_terminal_response_sanitizer.py fix(cli): tighten mouse leak sanitizer 2026-04-29 22:10:18 -05:00
test_cli_tools_command.py
test_cli_user_message_preview.py
test_compress_focus.py
test_cprint_bg_thread.py fix(cli): recover classic CLI output after resize 2026-05-06 04:20:54 -07:00
test_ctrl_enter_newline.py fix(cli): make Ctrl+Enter insert newline on WSL/SSH/Windows Terminal (#22777) 2026-05-09 12:48:14 -07:00
test_cwd_env_respect.py fix(cli): local backend CLI always uses launch directory, stops .env sync of TERMINAL_CWD (#19334) 2026-05-04 11:36:19 +05:30
test_destructive_slash_confirm.py fix: use TUI modal for slash confirmations 2026-05-11 10:02:03 -07:00
test_fast_command.py fix(anthropic): restrict fast mode to Opus 4.6 (Anthropic API contract) 2026-05-04 06:23:52 -07:00
test_gquota_command.py
test_manual_compress.py fix(cli): persist manual compress handoff 2026-05-05 04:42:48 -07:00
test_personality_none.py
test_prompt_text_input_thread_safety.py fix: use TUI modal for slash confirmations 2026-05-11 10:02:03 -07:00
test_quick_commands.py test: stabilize quick-command redaction test against xdist ordering 2026-05-10 22:12:23 -07:00
test_reasoning_command.py test: pin per-turn reasoning extraction semantics 2026-05-05 05:00:05 -07:00
test_resume_display.py fix(cli): recover classic CLI output after resize 2026-05-06 04:20:54 -07:00
test_save_conversation_location.py fix(sessions): /save lands under $HERMES_HOME, widen browse+TUI picker, force-refresh ollama-cloud on setup (#16296) 2026-04-26 18:49:48 -07:00
test_session_boundary_hooks.py
test_stream_delta_think_tag.py
test_surrogate_sanitization.py
test_tool_progress_scrollback.py
test_worktree.py
test_worktree_security.py