Skip to content

Terminal UI (pi-tui)

Since v0.2 Octipus ships two terminal surfaces built on top of @mariozechner/pi-tui — a differential renderer that writes only changed cells:

SurfaceCommandSourceUse it for
Chat shellocti tuisrc/tui-pi/Full-width conversation with the orchestrator
File editorocti editsrc/tui-editor/Three-pane split: file tree + buffer + side chat

Both surfaces share:

  • The same Editor primitive — paste markers, undo, history navigation, fuzzy @… / ./… file completion, slash-command autocomplete
  • The same overlay system — command palette and keybindings help layer above the content rather than reflowing it
  • The same KeybindingsManager — app-level bindings can be overridden in ~/.octipus/keybindings.json
  • The same agent context — files referenced via @… in either surface land in the same session
Terminal window
octi tui
  • Status bar with model, cumulative cost, and token budget
  • Streaming markdown rendering for assistant turns; plain wrap for user/system
  • Permission prompts inline; tool details visible (file path, command, URL)
  • /help overlay lists every gateway command
  • Glyphs auto-degrade to ASCII on terminals without proper emoji glyph support (detected via TERM_PROGRAM)
Terminal window
octi edit # current directory
octi edit ./some/path # specific path

Three panes — file tree (left), buffer (center), side chat (right). Pane heights are sized off tui.terminal.rows, so resizing the terminal reflows everything cleanly.

Open multiple files; cycle with Alt+, / Alt+. (or F2 / F3). The editor surface and the chat composer use the same Editor primitive, so the keystrokes you learn in one work in both.

Ctrl+O opens a fuzzy file picker. Filtering does substring match on the relative path (not prefix match on absolute path) — type any fragment, get any matching file.

CommandAction
/quit, /exit, /qClose all overlays then exit
/keysOpen the keybindings overlay (same as F5)
/paletteOpen the command palette (same as F4)

Some terminal byte collisions (Ctrl+M=Enter, Ctrl+H=Backspace, Ctrl+J=LF, Ctrl+I=Tab, Ctrl+[=Esc) ruled out the obvious choices, so these defaults sidestep them:

ActionBinding
Cycle buffer back / forwardAlt+, / Alt+. (also F2 / F3)
Command paletteF4
Keybindings helpF5
Cycle pane focusF6
File pickerCtrl+O
SubmitEnter
New lineShift+Enter

Override any of these in ~/.octipus/keybindings.json. The keybindings overlay (F5) is scrollable with / / PgUp / PgDn / Home and shows a “1–8 of 18” indicator so long lists don’t get truncated.

The TUI authenticates against the gateway hub the same way every other Octipus client does. Mint a personal octi_… api token in Settings → API Tokens and place it in ~/.octipus/local-token, or set OCTIPUS_TOKEN in the environment.

The MCP bootstrap token at ~/.octipus/mcp-token is not used by the TUI — the TUI prefers a user-owned token so audit attribution stays correct.

The previous implementation used Ink (React for the terminal). Pi-tui replaced it because:

  • The differential renderer is materially faster on long chats and large file buffers — only changed cells are written, no virtual DOM diff
  • The same Editor primitive backs both surfaces, so behavior stays consistent across chat composer and file buffer
  • KeybindingsManager is small enough that we can extend it with app-specific ids (app.palette.open, app.tree.toggle, …) without forking
  • Overlay rendering layers correctly above content instead of reflowing it

Glyphs render as boxes (e.g. 01F 4C1): your terminal doesn’t ship the emoji font. The TUI auto-falls-back to ASCII, but if you’re seeing raw codepoints, set TERM_PROGRAM=ascii or pick a terminal with full emoji support (Kitty, WezTerm, iTerm2, modern GNOME Terminal).

F1 opens the browser help: that’s the terminal hijacking F1, not the TUI. Use F5 for the keybindings overlay or remap in ~/.octipus/keybindings.json.

Ctrl+/ does nothing: terminals strip that to a control byte before pi-tui sees it. Use the configured binding (F4 palette, F5 keys) or override.

“Impersonation requires real session token”: the request isn’t carrying a real user session. Log in via the web UI to get a real session, or use a personal octi_… api token.