hermes - ✅(Solved) Fix Bug: TUI compound prompt symbols lose separator space in sent messages [1 pull requests, 1 participants]

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…
GitHub stats
NousResearch/hermes-agent#18996Fetched 2026-05-03 04:52:58
View on GitHub
Comments
0
Participants
1
Timeline
4
Reactions
0
Author
Participants
Timeline (top)
labeled ×3cross-referenced ×1

In hermes --tui, sent user messages can render with no visible separator between the prompt glyph and the message text when the active skin uses a compound or multi-column branding.prompt_symbol.

This is a general TUI transcript-rendering bug, not a skin-specific issue.

Root Cause

The TUI theme loader normalizes branding.prompt_symbol via cleanPromptSymbol(...).trim(), so trailing spacing from the skin definition is removed. The live composer accounts for prompt width dynamically, but sent transcript messages render through MessageLine with a hard-coded prompt gutter:

<NoSelect flexShrink={0} fromLeftEdge width={3}>
  <Text>{glyph}{' '}</Text>
</NoSelect>

For compound or wider prompt symbols, glyph + ' ' can exceed the fixed width-3 gutter. When that happens, the appended separator space is clipped and the message text appears attached to the prompt glyph.

Fix Action

Fixed

PR fix notes

PR #19010: fix(tui): scale transcript prompt gutter for compound prompt symbols

Description (problem / solution / changelog)

What does this PR do?

MessageLine reserved a hard-coded width={3} for the role glyph gutter and rendered {glyph}{' '} inside it. For any skin whose branding.prompt_symbol rendered wider than two cells (compound prompts like ❯❯, multi-codepoint branding glyphs, Ψ >), the trailing separator space was clipped and the message body visually attached to the prompt:

❯Okay        instead of        ❯ Okay

The composer side already shares one width formula: composerPromptWidth() in lib/inputMetrics.ts (stringWidth(promptText) + COMPOSER_PROMPT_GAP_WIDTH). Reuse that formula for the transcript gutter so the live composer and the saved transcript stay aligned for any prompt symbol width. The downstream content box is widened by the same formula so wider gutters don't squeeze the body.

Related Issue

Fixes #18996

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • ui-tui/src/components/messageLine.tsx — import composerPromptWidth; compute gutterWidth = composerPromptWidth(glyph) and use it for the <NoSelect width={...}> and the adjacent content <Box width={...}>.
  • ui-tui/src/__tests__/textInputWrap.test.ts — extends the existing composerPromptWidth suite with the compound-prompt regression cases (❯❯ → 3, ❯❯❯ → 4) the hardcoded gutter could no longer accommodate.

How to Test

  1. `cp ~/.hermes/skins/default.yaml ~/.hermes/skins/wide.yaml`
  2. Edit wide.yaml so branding.prompt_symbol: '❯❯'
  3. `hermes --tui --skin wide`, send a message.
  4. Confirm sent message renders as ❯❯ Okay (with a visible space), not ❯❯Okay.
  5. `cd ui-tui && npm test -- src/tests/textInputWrap.test.ts` → 18/18 pass.
  6. `npm run type-check` → clean.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits
  • I searched for existing PRs
  • My PR contains only changes related to this fix
  • I've run pytest tests/ -q and the touched suite passes
  • I've added tests for my changes
  • I've tested on my platform: macOS 15.x

Documentation & Housekeeping

  • I've updated relevant documentation — N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture — N/A
  • I've considered cross-platform impact — checked: stringWidth handles wide-codepoint cells consistently across terminals
  • I've updated tool descriptions/schemas if I changed tool behavior — N/A

Changed files

  • ui-tui/src/__tests__/textInputWrap.test.ts (modified, +10/-0)
  • ui-tui/src/components/messageLine.tsx (modified, +20/-9)

Code Example

Okay

---

❯Okay

---

<NoSelect flexShrink={0} fromLeftEdge width={3}>
  <Text>{glyph}{' '}</Text>
</NoSelect>
RAW_BUFFERClick to expand / collapse

Hermes TUI: compound prompt symbols lose separator space in sent messages

Summary

In hermes --tui, sent user messages can render with no visible separator between the prompt glyph and the message text when the active skin uses a compound or multi-column branding.prompt_symbol.

This is a general TUI transcript-rendering bug, not a skin-specific issue.

Reproduction

  1. Use any TUI skin whose branding.prompt_symbol renders wider than a one-column glyph, for example a compound prompt symbol with multiple visible characters.
  2. Start hermes --tui.
  3. Send a normal message.
  4. Observe the sent user message in the transcript.

Expected

The rendered transcript line preserves a visual separator between the prompt glyph and message body, for example:

❯ Okay

Actual

The message body can begin immediately after the prompt glyph, for example:

❯Okay

Root cause

The TUI theme loader normalizes branding.prompt_symbol via cleanPromptSymbol(...).trim(), so trailing spacing from the skin definition is removed. The live composer accounts for prompt width dynamically, but sent transcript messages render through MessageLine with a hard-coded prompt gutter:

<NoSelect flexShrink={0} fromLeftEdge width={3}>
  <Text>{glyph}{' '}</Text>
</NoSelect>

For compound or wider prompt symbols, glyph + ' ' can exceed the fixed width-3 gutter. When that happens, the appended separator space is clipped and the message text appears attached to the prompt glyph.

Suggested fix

Make the transcript user-message gutter width dynamic based on the rendered prompt glyph width, matching the composer’s composerPromptWidth() behavior, instead of hard-coding width={3}.

The fix should live in the transcript rendering path, not in individual skin files, because any skin with a sufficiently wide or compound prompt symbol can hit the same issue.

extent analysis

TL;DR

Make the transcript user-message gutter width dynamic based on the rendered prompt glyph width to fix the issue with compound prompt symbols.

Guidance

  • Identify the MessageLine component where the prompt glyph and message text are rendered, and locate the hard-coded width={3} gutter.
  • Replace the fixed gutter width with a dynamic value that accounts for the width of the rendered prompt glyph, similar to the composerPromptWidth() behavior in the live composer.
  • Verify that the fix works by testing with different skin configurations that use compound or multi-column branding.prompt_symbol values.
  • Consider adding a minimum gutter width to ensure a visible separator between the prompt glyph and message text, even for narrow prompt symbols.

Example

<NoSelect flexShrink={0} fromLeftEdge width={composerPromptWidth() + 1}>
  <Text>{glyph}{' '}</Text>
</NoSelect>

Notes

This fix assumes that the composerPromptWidth() function is available in the transcript rendering path. If not, an alternative approach may be needed to determine the dynamic gutter width.

Recommendation

Apply the suggested fix to make the transcript user-message gutter width dynamic, as it addresses the root cause of the issue and provides a flexible solution for different skin configurations.

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