Skip to content

Inspector: size to the terminal, page it, and a full-screen view - #4

Merged
navbytes merged 1 commit into
mainfrom
claude/pi-context-tree-workflow-sjuutd
Sep 4, 2026
Merged

Inspector: size to the terminal, page it, and a full-screen view#4
navbytes merged 1 commit into
mainfrom
claude/pi-context-tree-workflow-sjuutd

Conversation

@navbytes

@navbytes navbytes commented Sep 4, 2026

Copy link
Copy Markdown
Owner

Reported from real use: the inspector's right pane truncates, and there was no way to see the rest.

The caps were hardcoded and ignored the terminal —

block("Payload", JSON.stringify(st?.input ?? {}, null, 1), 8)
block("Result",  String(st?.output ?? ""),                10)
block("Text",    part?.text ?? row.preview,               14)

— so a tall window sat half empty under a dead … 61 more lines (y to copy), and the pane was a flat <For each={inspectorLines()}> with no scroll state at all.

Three changes, in the order they matter

1. The window is sized from the terminal. Every line is materialised (bounded by INSPECTOR_MAX_LINES only so a pathological payload cannot build an unbounded array per render) and the window comes from height(). A taller terminal simply shows more, with no new keys — this alone fixes the common case of a 30-line payload cut at 10 while the pane has room.

2. PgUp / PgDn page it, with no focus mode. j/k must keep driving the row selection, because that is what chooses the inspector's content; a "focus the pane" concept would add modality to a route that has none, and Tab is already fold/unfold. PgUp/PgDn were unbound, need no focus, and already mean "scroll a pane". The dead notice becomes a live position:

┃            "status": "completed"
┃ 12–40 of 118 · PgUp/PgDn · y copy · I full

The offset resets when the selected row changes — new content, new top.

3. shift+i opens it full screen (and from a closed inspector, opens it there directly), esc returns it to the side pane. A ~40-column pane is not a JSON viewer, so this is the "show me all of it" answer.

Bug fixed

showInspector() required cols() >= 110 with no fallback and no message, so on an 80-column terminal i flipped a flag that rendered nothing and said nothing — the inspector was simply dead. It now opens full screen there, which is both the fix and the pi-context-tree inspect view DESIGN.md §7.1 has promised since 0.1 and never shipped.

Where the logic lives

The scroll arithmetic went into core/navigation.ts#paneWindow / scrollPane rather than the route, because this is exactly where off-by-ones hide silently. Clamping is in the getter, not the setter, so a resize or a shorter row cannot strand the view past the end of the new content.

9 new tests: the last page sitting flush with the end rather than scrolling into blank space, symmetric up/down with both clamping, the two-line page overlap, paging down repeatedly landing on the last page and stopping, empty content reading 0 instead of 1–0 of 0, a one-line pane still advancing, and a deep offset surviving a switch to much shorter content.

What I deliberately did not do

Make this feel like a JSON viewer. y remains the answer for actually reading a large payload — somewhere with search and folding — and the pane footer keeps saying so. The scroller is for "there were twelve more lines and I want to glance at them"; full screen is for "show me the shape of this".

Tests

252 pass, 0 fail. Typecheck and build clean.

Not verified here: the e2e suite — opencode serve does not bind in this container (reproduced with no plugin installed at all). This is TUI-render and keybinding work covered by unit tests for the arithmetic, but the /tree e2e drives the real TUI and should cover it before release.

🤖 Generated with Claude Code

https://claude.ai/code/session_01BrwAnTfTmJSmFwVn3DDFxr


Generated by Claude Code

The inspector capped each field at a fixed 8 (Payload) / 10 (Result) /
14 (Text) lines whatever the terminal, so a tall window sat half empty
under a dead "… 61 more lines (y to copy)", and it had no scroll state
at all. Below 110 columns the side pane does not fit and `i` flipped a
flag that rendered nothing and said nothing, so the inspector was simply
dead on an 80-column terminal.

Three changes, in the order they matter:

1. The window is sized from height() instead of a constant. Every line
   is materialised (bounded by INSPECTOR_MAX_LINES only so a pathological
   payload cannot build an unbounded array per render), so a taller
   terminal shows more with no new keys at all.

2. PgUp/PgDn page it, with no focus mode: j/k must keep driving the row
   selection, because that is what chooses the inspector's content, and
   a focus concept would add modality to a route that has none. The
   arithmetic is core/navigation.ts#paneWindow / scrollPane — clamped in
   the getter, so a resize or a shorter row cannot strand the view past
   the end of the new content, and pages overlap by two lines. The foot
   of the pane reads "12–40 of 118 · PgUp/PgDn · y copy · I full"; the
   offset resets when the selected row changes.

3. shift+i opens it full screen, and from a closed inspector opens it
   there directly. This is also what `i` now does below 110 columns,
   which fixes the dead key and delivers the full-screen inspect view
   DESIGN.md §7.1 has promised since 0.1. esc returns it to the pane.

y stays the answer for actually reading a large payload — a ~40-column
pane is not a JSON viewer. The scroller is for "there were twelve more
lines and I want to glance at them".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BrwAnTfTmJSmFwVn3DDFxr
@navbytes
navbytes merged commit 115c55d into main Sep 4, 2026
1 check passed
@navbytes
navbytes deleted the claude/pi-context-tree-workflow-sjuutd branch September 4, 2026 05:26
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.

2 participants