feat(scene): restructure the trace frame as a three-pane Sidebar/Main/ContextPanel layout#1003
Merged
Conversation
…/ContextPanel layout Stage 1 toward the user's design mock — restructure from a flat column of rows to the classic IDE three-pane shape: ┌───────────── title (full width) ─────────────┐ │ SIDEBAR (24) │ MAIN (fill) │ CTX (32) │ └───────────── status (full width) ────────────┘ The middle band is a `direction: "row"` box with `height: "fill"`, made possible by the flex-sizing infra from #1000. Sidebar and ctx pane have fixed cell widths; main pane fills the remainder. Both side panes auto-hide on narrow terminals — sidebar below 60 cols, ctx pane below 100 cols — so an 80-col terminal still works the way it did before, just with a sessions-rail on the left. ## Main pane content (unchanged) The cards stack, composer / approval / sessions-picker takeover, slash overlay — exactly the same nodes as before, now living inside the main pane's column instead of inline in the root. ## Sidebar (stage-1 placeholder) Just a `─ SESSIONS ─` header + `use /sessions to browse` hint. The real session list goes here in stage 2 once App.tsx surfaces a permanently-loaded list (today it's loaded only when the picker is open). ## Context pane (uses what's wired) `─ CONTEXT ─` + `model · cards · wallet`. Wallet moves from the status row into the ctx pane when both are visible — avoids duplicating it. At cols < 100 the ctx pane is hidden and wallet stays on the right of the status row (as in #1001). ## Test rewrite The flat-children shape was load-bearing in 15 tests. Added two helpers — `mainOf(f)` / `statusOf(f)` / `titleOf(f)` — and rewrote each test to drill through the new structure. Coverage is identical in spirit (still asserts behavior of card rows, composer, approval modal, sessions picker, slash overlay, status segments) but expressed in terms of the new hierarchy. 3 new shape tests: - root is now `[title, middle, status]` (3 children, not 4-7) - sidebar hidden below 60 cols - ctx pane hidden below 100 cols Refs #868
esengine
added a commit
that referenced
this pull request
May 16, 2026
… palette (#1005) Closes the visual gap between the structural three-pane layout from #1003 and the user's design mock. Previously every cell defaulted to the terminal's stock bg/fg; now the trace frame honors a small palette derived from the mock's oklch tokens, panes carry rounded borders, and title / status rows sit on a panel-tinted bar. ## Schema + Rust render - `BoxLayout.background?: Color` — new field, same shape as `borderColor`. Schema added in both TS (types.ts) and Rust (scene.rs). - `render_box` now runs `apply_decoration(layout, buf, area)` before laying out children: - if `background` is set, fills every cell of the box area with that bg (via ratatui Block's style). - if `borderStyle` is set, draws ratatui's box-drawing perimeter (Plain/Double/Rounded/Thick) in `borderColor`, shrinking inner area by 1 cell on each side for children. - both are independent — bg without border (title/status bars) works, border without bg (debug outlines) works too. ratatui's `Block` widget already does the right thing for the combined case (fill then draw border on top), so we lean on that rather than rolling perimeter-drawing by hand. ## Design palette (`src/cli/ui/scene/theme.ts`) oklch tokens from the mock converted to hex once, frozen as `PALETTE.{bg, bg2, panel, card, border, borderStrong, fg, fg2, muted, accent, accentStrong, success, warning, danger, violet}`. Single source of truth — components don't pick raw colors anymore. ## Producer side - Outer frame: `background: PALETTE.bg` (dark blue-grey base, sits behind every pane). - Title row: `background: PALETTE.panel`, brand prefix glyph in `accent`, model name in `violet` (matches the gradient brand mark in the mock). - Sidebar + ctx pane: `borderStyle: round` + `borderColor: border` + `background: bg2`. Reads as two soft cards flanking the main pane, same shape as the mock's panel/card style (modulo CSS gradients which ratatui can't do). - Status bar: `background: PALETTE.panel`, busy/idle in warning/success hexes from the palette, wallet segment in success when present. - Section headers (`SESSIONS`, `CONTEXT`) drop the dash decoration and use bold accent — cleaner now that bordered panes provide the framing. ## Tests - Rust (6 new): box-drawing chars at perimeter for Single / Round / Double border styles, border color applied to perimeter cells, background fills every cell, border shrinks inner area by 1 on each side. - JS: existing 61 tests adjusted to the new shapes (status row is now always a box for its bg tint, busy/idle assert hex colors via PALETTE rather than named "green"/"yellow"). 2 new shape assertions: title/status carry a background; side/ctx panes carry borderStyle=round + background. `cargo test -p reasonix-render --test render` → 23/23. `npm run verify` → green via prepush gate. ## What's still aspirational Real CSS gradients, drop shadows, border-radius smoothness, custom fonts, hover states — ratatui can't do any of these and won't. That's the floor for "TUI-native faithful to the mock"; everything above is what we ship. Refs #868 Co-authored-by: reasonix <reasonix@deepseek.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stage 1 toward the user's design mock. Restructures the trace frame
from a flat column of rows into the classic IDE three-pane shape.
```
┌───────────── title (full width) ─────────────┐
│ SIDEBAR (24) │ MAIN (fill) │ CTX (32) │
└───────────── status (full width) ────────────┘
```
What
The middle band is a `direction: "row"` box with `height: "fill"`,
made possible by the flex-sizing infra from #1000. Sidebar and
context pane have fixed cell widths; main pane fills the remainder.
Both side panes auto-hide on narrow terminals — sidebar below
60 cols, context pane below 100 cols — so an 80-col terminal still
works the way it did before, just with a sessions rail on the left.
Main pane (unchanged behavior). Cards stack, composer / approval /
sessions-picker takeover, slash overlay — exactly the same nodes as
before, now living inside the main pane's column instead of inline
in the root.
Sidebar (stage-1 placeholder). Just `─ SESSIONS ─` header +
`use /sessions to browse` hint. The real session list goes here in
stage 2 once App.tsx surfaces a permanently-loaded list (today it's
loaded only when the picker is open). Doing this PR without real data
is deliberate — the structural change is large enough on its own,
and the placeholder honestly says "this is where it goes."
Context pane (uses what's wired). `─ CONTEXT ─` + `model · cards
· wallet`. Wallet moves from the status row into the ctx pane when
both are visible — avoids duplicating it. At cols < 100 the ctx pane
is hidden and wallet stays on the right of the status row (as in
#1001).
Test rewrite
The flat-children shape was load-bearing in 15 tests. Added three
helpers (`mainOf(f)` / `statusOf(f)` / `titleOf(f)`) and rewrote
each test to drill through the new structure. Coverage is identical
in spirit (cards / composer / approval modal / sessions picker /
slash overlay / status segments all still verified) but expressed
against the new hierarchy.
3 new shape tests:
`npm run verify` green via prepush gate (61 scene-trace tests).
Coming up (separate sub-PRs)
keep `sessionsPickerList` populated whether or not the picker is
open).
meter (telemetry/stats data).
Refs #868