hermes - 💡(How to fix) Fix TUI: markdown links inside markdown tables lose hyperlink metadata [5 pull requests]

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…

Hermes TUI markdown rendering preserves clickable markdown links in normal paragraphs, but links inside markdown table cells are flattened to plain text. The visible label remains, but the URL/hyperlink metadata is lost, so clicking the table cell cannot open the link.

Root Cause

Hermes TUI markdown rendering preserves clickable markdown links in normal paragraphs, but links inside markdown table cells are flattened to plain text. The visible label remains, but the URL/hyperlink metadata is lost, so clicking the table cell cannot open the link.

Fix Action

Fix / Workaround

Code Example

[Example](https://example.com)

---

| Site |
|---|
| [Example](https://example.com) |
RAW_BUFFERClick to expand / collapse

TUI: markdown links inside markdown tables lose hyperlink metadata

Summary

Hermes TUI markdown rendering preserves clickable markdown links in normal paragraphs, but links inside markdown table cells are flattened to plain text. The visible label remains, but the URL/hyperlink metadata is lost, so clicking the table cell cannot open the link.

Affected area

  • Repo: NousResearch/hermes-agent
  • Main files:
    • ui-tui/src/components/markdown.tsx
    • ui-tui/src/__tests__/markdown.test.ts
    • ui-tui/packages/hermes-ink/src/ink/components/Link.tsx

Current behavior

Markdown outside a table:

[Example](https://example.com)

is rendered through MdInline -> renderResolvedLink(...) -> <Link url=...>, so Hermes Ink stores hyperlink metadata and click handling can open the URL.

Markdown inside a table:

| Site |
|---|
| [Example](https://example.com) |

is rendered by renderTable(...), but table code calls stripInlineMarkup(...) and builds plain strings. The table displays Example, but no <Link>/ink-link node reaches the renderer, so the URL is not clickable.

Evidence from current code

  • MdInline handles markdown links via renderResolvedLink(...):
    • ui-tui/src/components/markdown.tsx:515-518
  • ResolvedLink emits <Link url={url}>:
    • ui-tui/src/components/markdown.tsx:172-188
  • Hermes Ink Link emits <ink-link href={url}>, which is what click/hover handling consumes:
    • ui-tui/packages/hermes-ink/src/ink/components/Link.tsx:17-35
  • Table rendering strips inline markdown before measuring/rendering:
    • width measurement: ui-tui/src/components/markdown.tsx:218
    • cell wrapping: ui-tui/src/components/markdown.tsx:317
    • no-wrap render builds a plain row string: ui-tui/src/components/markdown.tsx:365-382
    • vertical fallback uses stripInlineMarkup(cell): ui-tui/src/components/markdown.tsx:462-469
    • wrapped horizontal path renders entry.text as plain text: ui-tui/src/components/markdown.tsx:478-490
  • Existing TODO points at this exact limitation:
    • ui-tui/src/components/markdown.tsx:360-363
    • "All cells render as plain text via stripInlineMarkup. TODO: follow-up — format to ANSI then wrap with wrapAnsi for inline markdown preservation."

Expected behavior

Markdown links inside table cells should preserve hyperlink targets in all table layouts:

  1. Natural-width / no-wrap horizontal table.
  2. Wrapped horizontal table.
  3. Vertical fallback table.

Visible text should remain aligned and readable, and clicking the visible label should open the markdown target URL.

Non-goals

  • Do not change persisted assistant messages or protocol payloads.
  • Do not inject raw OSC-8 escape strings into table text.
  • Do not solve full CommonMark table parsing, such as escaped pipes in cells, unless needed for this fix.
  • Do not replace current width-aware table fallback behavior from merged PR #26195.

Prior art / related upstream items

No exact open issue/PR was found for "TUI markdown links inside markdown tables lose hyperlink metadata".

Relevant prior art:

Design risks

  • Raw OSC-8 strings are risky in Hermes CLI/TUI surfaces; several open/adjacent issues involve OSC-8 leakage through prompt_toolkit/Rich paths. Preserve links through existing Link/ink-link metadata instead.
  • Async useLinkTitle() can change visible link labels after first render. In tables, that can invalidate width calculations. Prefer stable labels for table layout, or explicitly freeze measured/rendered labels.
  • Fixing only one branch is incomplete: no-wrap, wrapped horizontal, and vertical fallback are separate render paths.
  • Wrapping/padding needs display-cell width, not UTF-16 length, and must keep the existing CJK/emoji alignment guarantees.
  • splitRow(...).split('|') is already simplistic; avoid expanding scope unless the implementation needs a minimal escaped-pipe guard.

Suggested implementation shape

Use TDD and keep this local to the TUI markdown renderer.

  1. Add regression tests in ui-tui/src/__tests__/markdown.test.ts that render a table containing [Example](https://example.com).
  2. Assert that output contains the URL in hyperlink metadata / OSC-8 output before stripping OSC sequences, not merely the visible label.
  3. Cover:
    • a table wide enough for the no-wrap path,
    • a constrained width that exercises wrapped horizontal table rendering,
    • a narrow/large-cell case that exercises vertical fallback.
  4. Keep existing table tests green, especially CJK display-offset alignment.
  5. Implement a small table-cell representation rather than raw strings:
    • parse inline cell content into visible text plus link/style spans, or reuse a constrained MdInline-like tokenization helper;
    • measure/wrap using visible text and stringWidth;
    • render visual segments with <Link> for the linked ranges;
    • pad outside the link range so padding is not clickable.
  6. Avoid raw ANSI/OSC generation inside markdown.tsx; let @hermes/ink produce OSC/link metadata from <Link>.

Acceptance criteria

  • Markdown links inside table cells are clickable in TUI output.
  • The visible table layout remains aligned for plain ASCII and CJK/wide-character tables.
  • Tests cover table link preservation across no-wrap, wrapped, and vertical fallback modes.
  • No provider/protocol/API behavior changes.
  • No raw OSC-8 escape sequences are manually embedded in table strings.

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…

FAQ

Expected behavior

Markdown links inside table cells should preserve hyperlink targets in all table layouts:

  1. Natural-width / no-wrap horizontal table.
  2. Wrapped horizontal table.
  3. Vertical fallback table.

Visible text should remain aligned and readable, and clicking the visible label should open the markdown target URL.

Still need to ship something?

×6

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

Back to top recommendations

TRENDING