Yes, you can run vim inside an agentic multiplexer: raw mode and the VT emulator
The credibility test for any AI terminal: open vim. Then htop. Then less. How rysh passes with a vt10x emulator, alt-screen detection, and raw mode.
There's a one-command credibility test for every "AI terminal" on the market: type vim.
Half of them shatter. Garbled escape codes, a frozen screen, arrow keys typing ^[[A into your buffer. Because underneath the AI gloss they aren't terminals — they're chat views wearing a monospace font.
Rysh's position: if it can't run vim, htop, less, and nano properly, it doesn't get to call its panes terminals. So we built the unglamorous thing that makes it true.
The problem, honestly stated
Interactive programs don't print lines — they paint screens. They switch the terminal to the alternate screen buffer, address the cursor directly, and repaint regions on every keystroke. A line-oriented pipeline ("read PTY output, append to a buffer, render") destroys them.
To host them you need an actual terminal emulator between the PTY and your renderer. So each rysh pane embeds one: a thread-safe wrapper around vt10x, maintaining a real 2D screen grid, cursor state, and mode flags.
The pane's PTY read loop is byte-based, not line-based — it pulls raw bytes (4KB reads) off the PTY and feeds them straight to the emulator. Escape sequences, cursor addressing, screen clears: interpreted properly, into a grid, not mangled into a log.
Auto-detection: the part you never think about
Here's the interaction design we're proudest of because it's invisible.
When a program activates the alternate screen buffer — as vim, htop, and less all do — the VT emulator notices the mode change, and the pane automatically enters raw mode. When the program exits and the alt screen deactivates, raw mode ends and the pane returns to its normal shell/prompt life.
You don't configure anything. You type vim, and vim just… works. You quit, and you're back in a pane where Double-Escape flips you to your AI. For the odd program that misbehaves (or when you want it manually), ##raw toggles raw mode by hand.
Raw mode: get out of the way, completely
In raw mode, the pane stops being clever:
- Every keystroke is forwarded as raw bytes to the PTY. The TUI translates key events into proper terminal byte sequences — arrows, function keys, Ctrl-combos, the lot — so vim receives exactly what a bare terminal would send.
- One escape hatch survives:
Ctrl+O. It enters rysh's prefix mode, from which you can switch panes, switch tabs, or detach the session. Everything else belongs to the program. - Rendering flips source. The pane renders the emulator's screen grid — the actual 2D cells plus cursor position carried in the pane snapshot — instead of the scrollback buffer. You're seeing what vim painted, cell for cell.
Latency gets special treatment. Keystrokes in raw mode don't take the polite route through the workspace actor like commands do — the TUI publishes them straight to the pane's own subject on the message bus. One hop, keyboard to PTY. Editing feels local because the path is as short as we could make it.
Size is negotiated, not assumed
Screen-painting programs are paranoid about dimensions, so rysh treats resize as a first-class event. On every window resize, the TUI computes each pane's real content area and sends a resize message that updates both the PTY (via TIOCSWINSZ — so vim learns the new size the Unix way) and the VT emulator's grid. Panes start at a sane 80×24 and get corrected on first render.
And the PTY environment advertises TERM=xterm-256color, so programs probe capabilities honestly — full-color htop, not monochrome fallback.
The detail that shows the architecture: remote viewers
Here's where "agentic multiplexer" and "real terminal" compose instead of fighting.
Rysh panes can be shared — with a teammate over the upstream server, or locally when another pane subscribes to your output. What happens when you're in vim and the shared stream would otherwise be a firehose of cursor-addressing escape codes?
The shared output path keeps receiving ANSI-stripped text even during raw mode. Your screen shows vim's live TUI; a remote observer sees readable content instead of escape-sequence soup. Your terminal is fully a terminal, and your collaboration stream is fully a stream — the same pane, projected two ways.
One honest caveat: a view-mode share of a vim session is a readable approximation, not a pixel-perfect mirror — screen-painting UIs are inherently lossy as text streams.
Why an agent platform bothers with this
Because the whole premise of rysh is that agents and humans share the same workspace, not adjacent ones.
Your agent runs git log through a pager. It opens less on a build log. You drop into vim in the very pane where an agent just proposed a diff, because sometimes hand-editing is faster than prompting. If interactive programs broke, you'd keep a "real terminal" open next to rysh — and the moment you do that, the shared-workspace premise is dead and it's copy-paste glue again.
The test for an agentic terminal isn't the demo where the AI writes code. It's vim. Boring, load-bearing, and in rysh: passing.
Rysh is early. If your team lives in the terminal and wants agents in it — not next to it — become a design partner: rysh.ai/design-partner
Related: Double-Escape · Shell, AI, chat, system: four output streams