Skip to article
Browse chapters

The terminal surface

The grammar bingo draws in, the keys that drive it, and how sub-agents and rooms appear as rows you can step into.

What is on screen

The terminal surface owns the whole screen for the run. Nothing sits above the transcript; the one line of furniture is under the input box.

  > what is in this workspace?

  ⏺ I'll read the manifest first.

  ⏺ Read(Cargo.toml)
    ⎿  Read 42 lines

  ⏺ reviewer(review the manifest)
    ⎿  Done (4 tools · 8.1k tokens · 40s)

  ⏺ One workspace, 27 crates: a kernel and its plugins.

  ✻ Tinkering… (esc to interrupt · 4s · ↓ 0.4k tokens)
  ╭──────────────────────────────────────────────────────────────╮
  │ > ▌                                                          │
  ╰──────────────────────────────────────────────────────────────╯
  ⏵⏵ accept edits on (shift+tab to cycle)   context 84%   gpt-5.4

The grammar

glyphmeans
>what you said, on a raised bar
⏺what the model said or did — a bullet per block
⎿what came back: a result, a receipt, a child’s progress
✻presence: the activity row while a turn runs, and the welcome mark

A tool row’s bullet carries its state: warm and pulsing while the call runs, green when it finished, red when it failed, dim while pending or interrupted. Colour never carries a fact alone — every state has a glyph or a word, so NO_COLOR and a monochrome terminal lose nothing.

A result folds to its tail with … +12 lines (ctrl+o to expand). The activity row’s verb is one of bingo’s own, drawn once per turn: Simmering, Noodling, Tinkering, Rummaging, Mulling, Weaving, Sketching, Percolating.

The status line

Three slots, under the input box:

  • left — the permission mode: ⏵⏵ accept edits on (shift+tab to cycle). default shows no mode, only the hint.
  • middle — only what is true now: 1 needs you (ctrl+g), 2 running, context 84%, or the latest notice for four seconds; ? for shortcuts while the box is empty and nothing else is true.
  • right — where you are and what you are on: in reviewer · gpt-5.4.

Keys

This is the binding table the ? panel reads, so a key is documented where it is bound.

keyswhat they do
entersend the message · open the focused block
shift+enternewline (ctrl+j · alt+enter · \ then enter)
escsheet → card → dropdown → interrupt
esc escrewind to an earlier turn
ctrl+cinterrupt · clear input · twice to exit
ctrl+dexit on an empty input
up/downprompt history at the first and last line
left/rightthe session strip · down opens it
ctrl+a/ctrl+estart / end of the line (home · end)
alt+b/alt+fmove one word
ctrl+w/ctrl+u/ctrl+kdelete word · to line start · to line end
pgup/pgdnscroll the transcript
ctrl+gswitch to a sub-agent’s view
ctrl+tplugin state (tasks, rooms)
tabcomplete the command under the caret
shift+tabcycle permission mode
1-9 · y/a/nanswer the open dialog
ctrl+eexpand the dialog’s preview
ctrl+oexpand the latest result · again for all of it
ctrl+bbackground the running command
/ · !run a command · run a shell line
?toggle the shortcuts panel

ctrl+f searches the transcript; the search row owns the keyboard until esc closes it. The mouse scrolls, clicks a card row or a child’s row, and drags a selection — it is never required.

esc is one ordered stack, closing the innermost layer first: a sheet, then the card that is asking (leaving a card is its own cancel or denial), then a dropdown, and with nothing open it interrupts the turn.

ctrl+o only ever opens further — folded to expanded to the pager — and esc folds again.

Sessions are rows

A sub-agent is a session with a parent, and a room is a session without a model (ADR-0002). Both are drawn by the same code as everything else, and both appear where they began, as a row in the transcript:

⏺ reviewer(review the manifest)
  ⎿  Starting…
  ⎿  Running… 3 tools · 1.2k tokens
  ⎿  Done (4 tools · 8.1k tokens · 40s)
  ⎿  Needs you

enter on that row steps into the child’s transcript, and the status line’s right slot then reads in reviewer. A room’s row is its name alone; inside a room, posts read as > reviewer: … and the prompt is #design > .

Two ways to move between them:

  • ctrl+g opens the switcher, a dropdown above the input box with one session per row — ❯ reviewer ⏺ running · needs you. enter goes there, esc closes it.
  • down on an empty composer turns the status line into a chip strip — ❯ ⏺ project ⏺ reviewer #design, agents then rooms — and left/right switch the view live as the cursor moves, wrapping at the ends. up, esc or typing gives the status line back.

A child that needs a person pulses until you go to it, and the status line counts it: 1 needs you (ctrl+g).

Panels and the rail

A plugin can put a live, journaled or one-off view on the screen without knowing what a terminal is (ADR-0013). Past 120 columns those become cards in a rail down the right-hand side — todos, a progress bar, a room’s open mentions; below 120 columns the same cards draw inline under the running rows. ctrl+t opens the panel sheet, where enter pins a panel into the rail for that session. tab walks the rail cards, and a digit fires the button a card names while the composer is empty.

The vocabulary a plugin writes in is UI as data.

Resuming

/resume opens a picker: the title bingo derived for the session, how many messages it holds, and how long ago it was touched.

Resume
❯ 1. fix the parser · 12 msgs · 2h ago
  2. 请帮我把这个解析器修好 · 1 msg · 1d ago
  3. untitled · 5d ago

/clear starts a fresh session in the same directory. From the shell, bingo --continue reopens the most recent session here and bingo --resume <id> reopens one by id.

Leaving

On exit the surface prints the last screenful of the conversation into the shell’s normal screen, so the transcript is still on your terminal afterwards. --no-print-on-exit leaves the terminal exactly as it was.

Environment

The look is settled before the kernel starts, so these are environment variables rather than settings:

variableeffect
NO_COLORno colour; weights and glyphs carry every fact
BINGO_MOTION=offevery cue holds at its resting frame
BINGO_ASCII=1ASCII stands in for the glyphs
BINGO_THEME=light | darkforce a palette instead of reading the terminal’s