Skip to content

Layout Engine

Eshan Roy edited this page Jun 30, 2026 · 1 revision

Layout Engine

M31 Autonomous (M31A) uses a CSS Flexbox-inspired layout system with responsive breakpoints, Z-order compositing, and a unified page chrome. The layout engine converts Box trees into rendered terminal output with proper spacing, borders, and alignment.

Source: internal/tui/layout/

Architecture

flowchart TD
    Screen[Screen Model] -->|Build| BoxTree[Box Tree]
    BoxTree -->|Solve| Solver[Layout Solver]
    Solver -->|3-Pass| Rendered[Rendered String]
    Rendered -->|Compose| Page[Page Chrome]
    Page -->|Header| Header[Header Zone]
    Page -->|Content| Content[Content Area]
    Page -->|Footer| Footer[Footer Zone]

    style Screen fill:#e1f5fe
    style Solver fill:#fff3e0
    style Page fill:#e8f5e9
Loading

Box Primitives

Source: internal/tui/layout/constraints.go

The Box is the fundamental layout primitive:

type Box struct {
    Width       int
    Height      int
    Flex        int           // flex grow factor (0 = fixed)
    Direction   FlexDirection // Column or Row
    Alignment   Align         // Start, Center, End
    Gap         int
    Padding     Insets
    Border      bool
    BorderColor string
    Background  string
    Content     string
    Children    []*Box
}

Flex Direction

Direction Description
Column Vertical layout (top to bottom)
Row Horizontal layout (left to right)

Alignment

Align Description
AlignStart Align to start (top/left)
AlignCenter Center alignment
AlignEnd Align to end (bottom/right)

Builder Functions

Function Description
NewRow() Create a horizontal box
NewColumn() Create a vertical box
WithContent(s) Set content string
WithFlex(n) Set flex grow factor
WithSize(w, h) Set fixed dimensions
WithPadding(insets) Set padding
WithBorder(color) Enable border
WithBackground(color) Set background color

Layout Solver

Source: internal/tui/layout/solver.go

The solver resolves the Box tree in three passes:

Pass 1: Allocate Fixed

Calculate sizes for boxes with fixed widths/heights (Flex=0).

Pass 2: Distribute Flex

Distribute remaining space to flex children proportionally.

Pass 3: Render and Join

Render each child and join with appropriate spacing.

func Solve(root *Box) string

The solver handles:

  • Row layout: horizontal distribution with vertical alignment
  • Column layout: vertical distribution with horizontal alignment
  • Padding and border rendering via lipgloss
  • Background color application

Convenience Functions

Source: internal/tui/layout/box.go

Function Description
RenderBox(content, w, h, opts...) Create, solve, and return a Box
RenderCard(title, content, w, border, borderColor, bg) Render a card-style box
SplitHorizontal(totalW, count, gap, fixed...) Distribute width among N children
SplitVertical(totalH, count, gap, fixed...) Distribute height among N children
FitContent(content, w, h) Pad or clip content to exact dimensions

Z-Order Compositing

Source: internal/tui/layout/stack.go

Layer compositing for overlays and modals:

type StackLayer struct {
    Content string
    X, Y    int
    Width   int
    Height  int
}
Function Description
RenderStack(width, height, layers) Composite layers by stamping onto 2D rune grid
RenderDimmed(content, theme) Apply ANSI faint attribute to all lines
RenderDimmedOverlay(base, overlay, w, h, theme) Dimmed base + centered overlay
RenderModalOverlay(base, modal, w, h, theme) ANSI-safe modal overlay

Page Chrome

Source: internal/tui/layout/page.go

Unified page layout composing header + content + footer. Every screen goes through RenderPage for consistent chrome.

Header

type HeaderInfo struct {
    Brand         string
    Breadcrumb    string
    Model         string
    Provider      string
    ContextUsage  float64  // 0.0 - 1.0
    ContextHistory []float64 // sparkline data
}

3-zone header: brand | breadcrumb + leader dots + right zone (context meter, model, provider)

Footer

type FooterInfo struct {
    CWD         string
    GitBranch   string
    Operation   string
    LeaderKey   bool
    Hints       string
    TokenCount  int
    Cost        float64
    SpinnerFrame string
}

3-zone footer: cwd + branch | operation + spinner | hints + cost

Context Meter

The context meter shows token usage with color thresholds:

  • Green: <70% usage
  • Yellow: 70-90% usage
  • Red: >90% usage

Includes a sparkline showing recent context usage history.

Responsive Breakpoints

Source: internal/tui/layout/responsive.go

Breakpoint Width Sidebar Header Right Footer Hints Footer Cost
UltraNarrow <40 No No No No
Compact 40-59 No No No No
Standard 60-79 No Yes Yes No
Full >=80 Yes Yes Yes Yes
Function Description
Detect(width) Returns breakpoint for terminal width
ShowSidebar(width) true at >=80 cols
ShowHeaderRight(width) true at >=60 cols
ShowFooterHints(width) true at >=60 cols
ShowFooterCost(width) true at >=80 cols

Minimum Screen Handling

Source: internal/tui/layout/minscreen.go

Function Description
RenderTooNarrow(w, h, theme) Centered "resize terminal" message for UltraNarrow
RenderOverlay(base, overlay, w, h, overlayW, theme) Right-aligned sidebar/modal overlay
truncateToWidth(s, maxW) ANSI-safe truncation preserving escape sequences

Integration

The layout engine is used by:

  • Page chrome: RenderPage composes header + content + footer
  • Sidebar: RenderOverlay for right-aligned panel
  • Modals: RenderModalOverlay for permission/confirmation dialogs
  • Screens: Individual screens build Box trees for their content
  • Components: Components use RenderBox for self-contained layouts

Clone this wiki locally