Skip to content

fix(tui): one-line list rows keep the selection in view; Windows-safe save-queue test - #2850

Merged
cliffhall merged 2 commits into
v2/mainfrom
v2/fix/2826-tui-truncate-list-rows
Oct 29, 2026
Merged

cliffhall merged 2 commits into
v2/mainfrom
v2/fix/2826-tui-truncate-list-rows

Conversation

@cliffhall

Copy link
Copy Markdown
Member

Closes #2826
Closes #2810

#2826: TUI list rows wrap in narrow terminals

  • One line per row. Tools, Resources and Prompts list rows render with wrap="truncate-end", so a long name gets an ellipsis instead of wrapping. The scroll window counts items, so a wrapped row used to push the selected row out of the clipped list box.
  • The selection stays visible on resize. useSelectableList now re-clamps the window on every render, not only when the selection moves. Before, shrinking the terminal reduced visibleCount but left a stale firstVisible, which could slice the selected row off the bottom. The clamp is the existing pure clampFirstVisible, run during render.
  • Full name in the detail pane; the hint drops below it when space is short. The Tools detail header is now flexWrap="wrap" with the [Enter to Test] hint in its own non-shrinking box. If the name and hint fit on one line they share it, as before. If not, the hint moves to the next line instead of the two overlapping. The Resources and Prompts headers have no inline hint and already showed the full name.
  • A tool row's schema-portability marker (! / ?, Feature: Strict JSON Schema validation with actionable error messages in CLI mode #1005) sits outside the truncated text, so the ellipsis never hides it.

#2810: saveResult.queue.test.ts hard-codes POSIX paths

This is a test-only change, as the issue's prompt describes. It adds const inD = (name: string) => resolve("/d", name) and uses it in the four assertions. On POSIX resolve("/d", "a.json") is still "/d/a.json", so nothing changes there. The source is untouched.

Screenshots

These are real pty captures of clients/tui/build/index.js node test-servers/build/test-server-stdio.js at 60×18, after c, t, Tab and seven ↓. The bytes were replayed through @xterm/headless and the final screen was rendered as text.

Before (v2/main): the selected mcp_app_demo is off-screen and the header overlaps its hint.
before

After: rows are truncated, the selected row is visible, and the hint sits below the full name.
after

After, short name: the hint stays beside the title when it fits.
after short

After, Resources list:
after resources

Tests

  • ToolsTab.test.tsx has a new narrow-terminal block with the issue's eight-tool fixture. It covers one-line truncated rows, the selected last row being visible, the selection staying visible after a height shrink, the hint wrapping below a long title, the hint staying beside a short one, and the marker surviving truncation. All five behaviour tests fail on v2/main.
  • PromptsTab / ResourcesTab tests check a truncated row plus the full name in the pane.
  • A useSelectableList test covers a visibleCount shrink.

🤖 Generated with Claude Code

cliffhall and others added 2 commits October 28, 2026 23:42
saveResultToFile resolves its target with node:path resolve(cwd, path),
so on Windows the mocked writeFile receives D:\d\a.json while the test
asserted POSIX literals. Build the expected paths the same way.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
…2826)

Tools, Resources and Prompts rows now render with wrap="truncate-end",
so a long name no longer wraps into extra rows that the item-counting
scroll window cannot see. The window is also re-clamped every render, so
a terminal resize cannot leave the selected row outside it. The Tools
detail header wraps its [Enter to Test] hint onto its own line when it
does not fit beside the full tool name, instead of overlapping it, and a
row's schema-portability marker sits outside the truncated text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>

Copilot AI 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.

🟢 Approval recommended

No active review issues are reported for the terminal-layout and cross-platform test-path changes.

No open issues 🎉

What changed in this PR

This PR fixes narrow-terminal layout issues in the Inspector TUI (#2826) and makes save-queue test assertions portable to Windows (#2810).

Changes:

  • Truncates Tools, Resources, and Prompts list rows while preserving tool schema markers and full names in detail panes.
  • Re-clamps the scroll window on resize and allows the Tools header hint to wrap below the title.
  • Adds layout regression tests and replaces POSIX-only expected paths with node:path.resolve.
File Description
clients/​tui/​src/​hooks/​useSelectableList.ts Re-clamps the visible window during render to keep selection visible.
clients/​tui/​src/​components/​ToolsTab.tsx Truncates rows, preserves schema markers, and wraps the header hint.
clients/​tui/​src/​components/​ResourcesTab.tsx Truncates resource list rows to one line.
clients/​tui/​src/​components/​PromptsTab.tsx Truncates prompt list rows to one line.
clients/​tui/​__tests__/​useSelectableList.test.tsx Covers selection visibility when the window shrinks.
clients/​tui/​__tests__/​ToolsTab.test.tsx Covers narrow layouts, resizing, header wrapping, and marker visibility.
clients/​tui/​__tests__/​saveResult.queue.test.ts Builds platform-native expected paths without changing production code.
clients/​tui/​__tests__/​ResourcesTab.test.tsx Checks truncated rows and full resource names in the detail pane.
clients/​tui/​__tests__/​PromptsTab.test.tsx Checks truncated rows and full prompt names in the detail pane.

Review effort: Balanced

@cliffhall

Copy link
Copy Markdown
Member Author

Copilot review loop closed: round 1 came back clean ("No open issues", 0 inline comments, nothing suppressed). Exit: first clean round, so I did not request a confirming round.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v2 Issues and PRs for v2

Projects

None yet

2 participants