forked from anomalyco/opencode
-
Notifications
You must be signed in to change notification settings - Fork 0
Closed as not planned
Closed as not planned
Copy link
Description
Description
Implement ANSI scroll region architecture for oclite — scrollable conversation area with fixed bottom panel.
Problem
After removing alt screen buffer (#66), oclite writes everything append-only to the main terminal buffer. This means:
- ❌ Cannot rewrite tool status lines once scrolled
- ❌ Cannot have a persistent status bar
- ❌ Cannot show live metrics during streaming
- ❌ Cannot have a fixed input area
Solution: ANSI Scroll Regions
Use \x1b[{top};{bottom}r to define a scroll region that covers most of the terminal, with 2-3 fixed lines at the bottom.
Layout:
┌─────────────────────────────────────┐
│ Scrollable conversation area │ ← Scroll region (rows 1 to N-3)
│ User messages, agent responses │
│ Tool output, markdown text │
│ ...scrolls naturally... │
│ │
├─────────────────────────────────────┤
│ ◆ Thinking · 5s · 3/5 tools │ ← Fixed status line (row N-2)
│ project-manager ❯ █ │ ← Fixed input line (row N-1)
│ Esc cancel · Shift+Tab agents │ ← Fixed hint bar (row N)
└─────────────────────────────────────┘
Requirements
Scroll Region Setup
- On startup: query terminal size, set scroll region
\x1b[1;{rows-3}r - Handle
SIGWINCH(terminal resize) — recalculate and reset scroll region - On cleanup: reset scroll region to full terminal
\x1b[r
Fixed Bottom Panel (3 lines)
- Status line: During streaming shows spinner + elapsed time + tool count + token count. During idle shows nothing or session info.
- Input line: Prompt + user input (
project-manager ❯ █) - Hint bar: Context-sensitive keyboard shortcuts (
Esc cancel · Shift+Tab agents · /help)
Writing to Scroll Region
- All conversation output (text, tool display, errors) writes to scroll region
- Scroll region scrolls naturally — old content preserved in scroll buffer
- New content appends at bottom of scroll region, pushing old content up
Writing to Fixed Panel
- Use
\x1b[s(save cursor) before updating fixed lines - Move to fixed line with
\x1b[{row};1H(absolute position) - Write content + clear to end of line
- Use
\x1b[u(restore cursor) to return to scroll region - Update fixed panel without disturbing scroll region content
Terminal Resize Handling
- Listen for
SIGWINCHsignal - Recalculate scroll region boundaries
- Redraw fixed bottom panel
- Preserve scroll position in conversation area
Implementation Plan
- Create
src/cli/lite/layout.ts— scroll region manager - Modify
index.ts— use layout manager for all writes - Modify
spinner.ts— render in status line instead of scroll region - Modify
bottombar.ts— render in fixed input/hint lines
Depends On
- None (foundational)
Blocks
- [UX] oclite: Rich status bar with streaming metrics #67 Rich status bar (renders in fixed status line)
- [UX] oclite: Live subagent status panel #68 Subagent panel (renders in scroll region or status line)
- [UX] oclite: Bottom context bar with workspace info #69 Bottom context bar (renders in fixed hint bar)
Technical Reference
- ANSI scroll region:
\x1b[{top};{bottom}r(DEC origin mode) - Terminal size:
process.stdout.rows,process.stdout.columns - Resize signal:
process.on('SIGWINCH', handler) - Save/restore cursor:
\x1b[s/\x1b[u - Absolute position:
\x1b[{row};{col}H
Files
- New:
packages/opencode/src/cli/lite/layout.ts - Modified:
packages/opencode/src/cli/lite/index.ts - Modified:
packages/opencode/src/cli/lite/spinner.ts - Modified:
packages/opencode/src/cli/lite/bottombar.ts
Metadata
Metadata
Assignees
Labels
No labels