Skip to content

fix(mcp): window the scope picker to the terminal height - #8

Merged
andrespineli merged 1 commit into
mainfrom
fix/mcp-scope-selector
Aug 11, 2026
Merged

fix(mcp): window the scope picker to the terminal height#8
andrespineli merged 1 commit into
mainfrom
fix/mcp-scope-selector

Conversation

@andrespineli

@andrespineli andrespineli commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Bug

On the /mcp token screen ("Select the resources the MCP server may access"), the scope list rendered incomplete and unstable on common terminal sizes:

  • entries were missing — group headers, the read scopes and clusters:provision:plan did not show;
  • the visible rows shifted/overlapped on every cursor move;
  • as a result, tokens could not be minted with the hidden scopes (e.g. clusters:read, clusters:provision:plan), breaking the plan→apply flow over MCP.

Reproducible with ink-testing-library at the default 30-row height: adjacent rows were overlaid and corrupted (e.g. Provision infrastructure (apply)des and VMs).

Root cause

ScopePicker (tui/ink/src/mcp/scope-picker.tsx) rendered the full grouped catalogue — about 30 lines — with no viewport, inside ScreenFrame, whose root box is pinned to the terminal height (height={rows}, screen-frame.tsx:100). When the list is taller than the space left by the chrome, yoga shrinks the body (flexShrink/minHeight: 0) and Ink overlays the overflowing rows, so seemingly arbitrary lines disappear — and the dropped set changes as the cursor re-renders. The scope catalogue itself was never the problem: both the UI catalogue and server/src/shared/inbound/mcp/scope/catalog.ts contain every scope.

Fix

Flatten the grouped catalogue into render lines (headers, scopes, spacers) and window it around the cursor, following the existing viewport pattern of the Select primitive, with dimmed ▲/▼ n more markers for the clipped remainder. Group headers stay attached to their first scope at the window edge; on tall terminals the full list still renders unwindowed. Navigation (flat cursor over scopes, space toggles, enter confirms) is unchanged.

Tests

  • New regression test in tui/ink/tests/mcp/mcp-screen.test.tsx: walks the cursor across the whole catalogue and asserts the previously-dropped rows are visible up front, no frame overflows the terminal height, and every scope and group renders during navigation.
  • Local gate: deno fmt --check, deno task lint, deno task check, deno task test — 622 passed, 0 failed.

The /mcp scope list rendered all ~30 lines of the grouped catalogue
inside the fixed-height ScreenFrame (height = terminal rows). On common
terminal sizes yoga shrank the body and Ink overlaid the overflowing
rows, so arbitrary entries vanished (group headers, the read scopes,
clusters:provision:plan) and the visible set shifted on every cursor
move — tokens could not be minted with the hidden scopes.

Flatten the grouped catalogue into lines and window it around the
cursor, following the Select primitive's viewport pattern, with
dimmed '▲/▼ n more' markers for the clipped remainder. Group headers
stay attached to their first scope at the window edge. On tall
terminals the full list still renders unwindowed.
@andrespineli
andrespineli merged commit 108755a into main Aug 11, 2026
4 checks passed
@andrespineli
andrespineli deleted the fix/mcp-scope-selector branch August 11, 2026 12:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant