Skip to content

fix(tui): clear selection on right-click copy + clearer block boundaries#37786

Merged
OutThisLife merged 1 commit into
mainfrom
bb/tui-rightclick-and-boundaries
Jun 3, 2026
Merged

fix(tui): clear selection on right-click copy + clearer block boundaries#37786
OutThisLife merged 1 commit into
mainfrom
bb/tui-rightclick-and-boundaries

Conversation

@OutThisLife

@OutThisLife OutThisLife commented Jun 3, 2026

Copy link
Copy Markdown
Collaborator

What

Screenshot 2026-06-02 at 22 30 34

Two TUI polish fixes.

1. Right-click copy clears the selection

Right-click-to-copy used onCopySelectionNoClear() (the copy-on-select variant that keeps the highlight during a drag), so after a right-click copy the selection stayed lit, there was no confirmation, and a follow-up right-click re-copied the stale range instead of pasting. A successful right-click copy now clears the highlight and notifies; if the copy fails (no clipboard path) the highlight survives and we fall back to the right-click paste handler. Right-click with nothing selected still pastes.

packages/hermes-ink/src/ink/components/App.tsx.

2. Group transcript blocks so boundaries read clearly

Model replies, reasoning/tool trails, and system/error notes rendered with no vertical separation — distinct block types butted together and were hard to scan.

Adjacent blocks are now grouped by kind: one blank line opens only where the visual group changes (model prose ↔ reasoning/tool trails ↔ notes), while a run of same-kind blocks renders flush. (This is the flex-grouping idea, but expressed as a per-row lead gap because the transcript is virtualized — a wrapper div spanning rows would break the per-row offset cache.)

The rule lives in domain/blockLayout.ts (messageGroup + hasLeadGap) and is applied intrinsically inside MessageLine via a prev prop. That placement fixes the two things ad-hoc per-block margins kept breaking:

  • Streaming stability — the gap is derived from the stable predecessor, never the live block's own changing text, so the actively-streaming reply computes the same gap while it streams as the settled segment does once it flushes. No reflow/jump.
  • Hidden details — a trail hidden by /details renders nothing and is transparent to grouping (prevRenderedMsg skips it), so there are no floating or doubled gaps. In the default/collapsed modes trails always render, so the grouping is a no-op there.

The virtual-height estimator (virtualHeights.ts + useMainApp) counts the group-boundary line so scroll math stays accurate before Yoga remeasures.

ui-tui/src/domain/blockLayout.ts (new), components/messageLine.tsx, components/streamingAssistant.tsx, components/appLayout.tsx, lib/virtualHeights.ts, app/useMainApp.ts.

Tests

  • app-mouse.test.ts — clears highlight on successful copy; keeps it when copy fails.
  • blockLayout.test.ts (new) — grouping relationships + hidden-trail visibility (no snapshots).
  • virtualHeights.test.ts — group-boundary lead gap adds one row.

Full ui-tui suite green apart from 3 pre-existing local/env failures (cursorDriftRegression, ink-resize, virtualHeights user-prompt-width) that fail identically on main. Type-check error count matches main (18, all in execFileNoThrow.ts; zero in touched files).

Notes

  • No ui-tui/package-lock.json committed (repo doesn't track one).

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

🔎 Lint report: bb/tui-rightclick-and-boundaries vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 9707 on HEAD, 9707 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 5029 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/tui Terminal UI (ui-tui/ + tui_gateway/) labels Jun 3, 2026

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

Verdict: Approved

Overview

Clean UX fix: clears selection after right-click copy in TUI and adds clearer visual boundaries between message blocks. Well-scoped, minimal changes.

✅ Looks Good

  • Right-click copy clearing selection is a standard UX pattern that prevents confusion
  • Block boundary improvements make the chat read more naturally
  • Small, focused change (103 additions, 7 deletions)
  • No security, performance, or correctness concerns

Reviewed by Hermes Agent

@OutThisLife OutThisLife force-pushed the bb/tui-rightclick-and-boundaries branch from bdc2a24 to cfb4c6f Compare June 3, 2026 02:40
Two TUI polish fixes.

(1) Right-click copy now clears the highlight.
The right-click handler copied an active selection via onCopySelectionNoClear
(the copy-on-select variant that keeps the highlight during a drag) and never
cleared it, so after right-click-to-copy the selection stayed lit with no
confirmation and a follow-up right-click re-copied the stale range instead of
pasting. A successful right-click copy now clears the selection and notifies;
if the copy fails (no clipboard path) the highlight survives and we fall back
to the right-click paste handler, exactly as before.

(2) Group transcript blocks so boundaries read clearly.
Model replies, reasoning/tool trails, and system/error notes rendered with no
vertical separation, so distinct block types butted together and were hard to
scan. Group adjacent blocks by kind: one blank line opens only where the visual
group changes (model prose <-> reasoning/tool trails <-> notes), while a run of
same-kind blocks renders flush. The rule lives in domain/blockLayout.ts
(messageGroup + hasLeadGap) and is applied intrinsically in MessageLine via a
`prev` prop, which fixes the things ad-hoc per-block margins kept breaking:

  - Streaming stability: the gap is derived from the stable predecessor, never
    the live block's own changing text, so the actively-streaming reply computes
    the same gap while it streams as the settled segment does once it flushes.
    No reflow/jump.
  - Transparent empty trails: a trail hidden by /details, or one carrying only a
    token tally (the finalDetails segment message.complete appends), renders
    nothing and is transparent to grouping (prevRenderedMsg skips it), so there
    are no floating gaps, no doubled gap after a prompt, and no padded space
    above the final reply. In the default/collapsed modes content-bearing trails
    always render, so the grouping is a no-op there.

The virtual-height estimator counts the group-boundary line so scroll math
stays accurate before Yoga remeasures.

ui-tui/src/domain/blockLayout.ts (new), components/messageLine.tsx,
components/streamingAssistant.tsx, components/appLayout.tsx,
lib/virtualHeights.ts, app/useMainApp.ts.

Tests: blockLayout.test.ts (grouping + hidden/empty-trail visibility),
virtualHeights leadGap, app-mouse.test.ts copy behavior. Full ui-tui suite
green apart from 3 pre-existing local/env failures (cursorDrift, ink-resize,
virtualHeights user-prompt-width) unchanged from main.
@OutThisLife OutThisLife force-pushed the bb/tui-rightclick-and-boundaries branch from cfb4c6f to dfba3f3 Compare June 3, 2026 03:03
@OutThisLife

Copy link
Copy Markdown
Collaborator Author

bugbot run

@cursor

cursor Bot commented Jun 3, 2026

Copy link
Copy Markdown

Skipping Bugbot: Unable to authenticate your request. Please make sure Bugbot is properly installed and configured for this repository.

@OutThisLife OutThisLife merged commit b6da66c into main Jun 3, 2026
20 checks passed
@OutThisLife OutThisLife deleted the bb/tui-rightclick-and-boundaries branch June 3, 2026 03:43
davidgut1982 pushed a commit to davidgut1982/hermes-agent that referenced this pull request Jun 5, 2026
…lick-and-boundaries

fix(tui): clear selection on right-click copy + clearer block boundaries
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/tui Terminal UI (ui-tui/ + tui_gateway/) 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.

3 participants