Skip to content

Fixed TUI list selection bug#1151

Open
BobDickinson wants to merge 2 commits intomodelcontextprotocol:v1.5/mainfrom
BobDickinson:react-and-ink-upgrade
Open

Fixed TUI list selection bug#1151
BobDickinson wants to merge 2 commits intomodelcontextprotocol:v1.5/mainfrom
BobDickinson:react-and-ink-upgrade

Conversation

@BobDickinson
Copy link
Contributor

Summary

The TUI has a list selection bug for Resources, Prompts, and Tools that made it impossible to navigate the lists (continually reselected first item).

Type of Change

  • Bug fix (non-breaking change that fixes an issue)

Changes Made

Fixed hook to only reselect first item when server changes

Testing

  • Tested in UI mode
  • Tested with STDIO transport
  • Tested with Streamable HTTP transport
  • Manual testing performed

Checklist

  • Code follows the style guidelines (ran npm run prettier-fix)
  • Self-review completed

Breaking Changes

None

@BobDickinson BobDickinson added the v1.5 Issues and PRs for v1.5 label Mar 16, 2026
@BobDickinson
Copy link
Contributor Author

@claude review

@claude
Copy link
Contributor

claude bot commented Mar 16, 2026

Claude finished @BobDickinson's task in 44s —— View job


Code Review

  • Gather context
  • Read changed files
  • Provide review feedback

The fix is clean and correctly addresses the root cause. Here's my analysis:

What changed

useSelectableList.ts — The core fix. The useEffect that resets selection now properly depends on options?.resetWhen (an object reference), so it only fires when the reference changes, not on every render or every data update.

ToolsTab.tsx, PromptsTab.tsx, ResourcesTab.tsx — Now pass { resetWhen: tools/prompts/resources } (the array reference) instead of what was presumably a value like tools.length that would change more frequently.

The fix is correct ✓

Passing the array reference as resetWhen ensures:

  • Selection resets to 0 only when the server provides a completely new list (new reference)
  • Normal data refreshes that return the same-reference array won't disrupt navigation
  • The clamping useEffect (lines 50–58) still handles shrinking lists correctly

Minor observations

  1. ResourcesTab resets on resources but not resourceTemplates (ResourcesTab.tsx:72). If only templates change (while resources stay the same reference), selection won't reset. This is probably fine in practice since both are fetched together, but worth noting.

  2. Redundant guard in the reset effect (useSelectableList.ts:43): The if (options?.resetWhen !== undefined) check is unnecessary — if resetWhen is undefined, the dependency [options?.resetWhen] won't track a meaningful change anyway. Harmless, but slightly noisy.

  3. Optional chaining in dependency array (useSelectableList.ts:47): Using options?.resetWhen as a dependency is fine here, but ESLint's react-hooks/exhaustive-deps can sometimes warn about optional chains. If the linter is clean, no action needed.

  4. useEffect fires on mount: On initial render the effect runs and sets selectedIndex to 0 (which it already is), so the initial reset is a safe no-op.

Overall

The approach is sound — using reference identity of the list as a reset signal is idiomatic and avoids over-resetting. The bug fix is minimal, targeted, and doesn't introduce new complexity.

Approved — no blocking issues.

@BobDickinson
Copy link
Contributor Author

The Resources tab feedback is not unreasonable, but given that it works as is and that we're going to do a pretty big TUI UX refactor at some point before release, I'm inclined to leave this as-is. I don't find any of the other feedback action-worthy (local agent agreed).

@BobDickinson BobDickinson requested a review from cliffhall March 16, 2026 17:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v1.5 Issues and PRs for v1.5

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants