hermes - 💡(How to fix) Fix persistent_output replay strips ANSI/Rich formatting after terminal resize

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

When display.persistent_output: true is set, terminal resize triggers _recover_after_resizeerase_screen() + _replay_output_history(). The replayed content is plain text only — all Rich Markdown rendering (tables, code blocks, bold, panels) is lost.

Root Cause

_record_output_history strips all ANSI escape codes before storing (cli.py ~line 1416):

clean = _ANSI_CONTROL_RE.sub("", str(text)).replace("\r", "").rstrip("\n")

So the history buffer only contains raw text. When replayed, Rich-rendered output (tables, borders, colors) is gone.

Additionally, _recover_after_resize sends \x1b[3J (erase saved lines), which wipes the terminal's native scrollback buffer (including iTerm2), leaving no fallback for the user to scroll up and see prior output.

Code Example

clean = _ANSI_CONTROL_RE.sub("", str(text)).replace("\r", "").rstrip("\n")

---

display:
  final_response_markdown: render   # Rich Markdown enabled
  streaming: false                  # Rich Panel used for final response
  persistent_output: true
RAW_BUFFERClick to expand / collapse

Summary

When display.persistent_output: true is set, terminal resize triggers _recover_after_resizeerase_screen() + _replay_output_history(). The replayed content is plain text only — all Rich Markdown rendering (tables, code blocks, bold, panels) is lost.

Root Cause

_record_output_history strips all ANSI escape codes before storing (cli.py ~line 1416):

clean = _ANSI_CONTROL_RE.sub("", str(text)).replace("\r", "").rstrip("\n")

So the history buffer only contains raw text. When replayed, Rich-rendered output (tables, borders, colors) is gone.

Additionally, _recover_after_resize sends \x1b[3J (erase saved lines), which wipes the terminal's native scrollback buffer (including iTerm2), leaving no fallback for the user to scroll up and see prior output.

Affected Config

display:
  final_response_markdown: render   # Rich Markdown enabled
  streaming: false                  # Rich Panel used for final response
  persistent_output: true

Expected Behavior

After resize, replayed history should preserve the same Rich formatting that was originally rendered — or at minimum, not erase the terminal's native scrollback (\x1b[3J) so the terminal's own scrollback buffer (iTerm2, Warp, etc.) acts as a fallback.

Suggested Fix

Store rendered ANSI output in _OUTPUT_HISTORY (before stripping), and replay with _pt_print(_PT_ANSI(entry)) instead of plain text. Alternatively, skip \x1b[3J so the terminal's native scrollback (iTerm2, Warp, etc.) acts as a fallback.

Environment

  • Hermes Agent v0.13.0 (2026.5.7)
  • macOS / iTerm2
  • Python 3.11

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - 💡(How to fix) Fix persistent_output replay strips ANSI/Rich formatting after terminal resize