atrium — Docs
docs/panes/terminal.md

Terminal pane: shells and CLI agents in a tile

xterm.js terminals with a composer for agent CLIs, clickable file paths, find in scrollback, shell integration, and scrollback that survives quit and crash.

Terminal panes are the default pane type and host everything that runs in a shell — interactive shells, agent CLIs, scripts, long-running dev servers.

For a project on an SSH location, the PTY and process run on that box while xterm.js renders in the macOS app. Disconnecting leaves the process alive and the last-known terminal read-only; reconnect attaches to the same PTY and scrollback.

For agents specifically, a terminal pane runs the tool's own TUI. If you would rather read the work as a structured transcript, launch into an agent chat pane instead.

Opening

  • Cmd+T opens a new room with a terminal pane.
  • Cmd+D / Cmd+Shift+D split the focused pane and open a terminal in the new split.
  • Drag the Terminal row from the Home sidebar and drop it into a split zone.

The launcher

A fresh pane opens with the launcher — a composer where you type what you want done and pick who does it. See Launching agents. Cmd+L brings it back on a focused pane.

The composer

Adapter panes get a composer below the terminal, on by default. It is the same composer shell the launcher and chat panes use, so @ references, sigil chips, file attachments, and slash commands behave identically everywhere.

  • Enter sends by default.
  • Esc interrupts, and re-inserts your message highlighted so you can edit and resend.
  • Shell-style history — arrow up and down through what you have sent, with caret-edge navigation so arrows only leave the field once the caret is already at the edge.
  • Drop anywhere on the pane to attach a file to the composer.
  • Drag a pane, room, project, or agent session onto the composer to insert a stable atrium reference rather than manually copying an ID.
  • Open Saved prompts from the + menu to reuse, rename, or delete prompt templates shared with the launcher and chat composer.
  • Type from empty and the keystrokes drive the terminal directly — a leading / or ! is forwarded rather than captured, so slash commands and shell escapes reach the tool. Backspacing away the leading / ends the capture.
  • Cmd/Ctrl+Shift+V pastes as plain text.
The composer card matches the pane's corner radius, its toolbar is toggleable, and clicking anywhere on the card focuses the editor.

Reader mode

Reader mode caps the content column and centers it, so a wide terminal doesn't produce unreadably long lines. It turns on automatically at 120 columns and can be toggled per pane from the header's View options. The composer matches its width, and the gutter forwards wheel events into the terminal so scrolling in the margin still works.

Recent prompts

Adapter session panes carry a recent-prompts strip — the things you have sent recently, one click to re-send. It is vertically resizable.

Working in a terminal

  • Full xterm.js rendering with WebGL acceleration.
  • Cmd+F opens a find bar that searches the scrollback, with match highlighting and jump-to-next.
  • Cmd+C copies the current selection. If nothing is selected, it sends SIGINT to the foreground process.
  • Cmd+A selects all scrollback.
  • Right-click a terminal pane for copy / paste / select-all, jump to cwd in the file tree, and pane-level actions like close, rename, and move to another room.
  • Clickable file paths and URLs — paths like src/foo.ts:12 and https://… are clickable, and are linkified even when they wrap across lines. Paths open an editor pane at the right line; URLs open in a browser pane, or in your system browser with Option+click.
  • Copy on select — an optional setting that copies the selection the moment you make it, with a confirmation chip so you know it landed.
  • File drops and paths are framed for agents — dropping a file onto a terminal pane, or pasting an absolute path, inserts it as @"/full/path" so harnesses like Claude Code and Codex pick it up as a file reference instead of raw text.
  • Image paste — pasting an image with Cmd+V into a harness pane attaches it as an image; pasting a non-image file inserts its path as the @"…" reference above.
  • The pane header shows the foreground process name and exit state, and highlights a dirty indicator if output is pending for a hidden pane.

Customizing terminal code

Shared code typography lives in Settings → Appearance → Code and updates terminal output, editors, diffs, markdown code, and transcript code together:

  • Font family, size, line height, letter spacing, ligatures. Powerline / Nerd Font glyphs render through an automatic fallback chain — your primary font does not need to be a Nerd Font–patched build for prompts like p10k, starship, or oh-my-posh to display their icons correctly.
Terminal-only appearance lives in Settings → Terminal:
  • Cursor style (block / underline / bar) and blink.
  • Scrollback line count.
  • Inner padding.
  • Background opacity.
Changes apply immediately. See Appearance.

Persistence

Terminals are fully resumable across quits, crashes, and reboots:

  • Scrollback is captured as the xterm grid and replayed on reopen.
  • Working directory, shell, adapter type, and adapter session ID are restored.
  • If the last command exited non-zero or was signal-killed, the pane records it so the Activity sidebar can offer a Replay action.
See Persistence & recovery for the full model.

Shell integration and environment

When atrium launches a shell it transparently installs a minimal integration layer so it can emit command-start and command-end events, track the foreground process name, and route hook events to the adapter.

  • For zsh, atrium sets ZDOTDIR to ~/.atrium/zsh/ with wrapper dotfiles that source your real dotfiles and add the hooks. Your .zshrc still runs normally.
  • For bash, atrium chains its hooks onto PROMPT_COMMAND, preserving any existing value as ATRIUM_EXISTING_PROMPT_COMMAND.
  • A USR1 signal to any atrium shell re-sources ~/.atrium/shell/env.sh, letting settings changes propagate into running shells without restarting them.
Every atrium shell also gets a small set of environment variables that identify the pane (ATRIUM_PANE_ID, ATRIUM_WORKSPACE_ID, ATRIUM_TAB_ID) and point at the CLI (ATRIUM_CLI_PATH). See Agents & adapters for the full contract.

Scripting a terminal pane

Terminal panes are discoverable and writable from the atrium CLI. Agents use this surface to inspect each other; you can use it from any shell to script a pane:

# List every pane
"$ATRIUM_CLI_PATH" pane list

# Read the last 200 rendered lines (what the user sees)
"$ATRIUM_CLI_PATH" pane read <id> --lines 200

# Write text to the PTY stdin
"$ATRIUM_CLI_PATH" pane write <id> --text "pnpm build"

# Focus, rename, resize, close
"$ATRIUM_CLI_PATH" pane focus  <id>
"$ATRIUM_CLI_PATH" pane rename <id> --name "build server"
"$ATRIUM_CLI_PATH" pane resize <id> --width 120 --height 40
"$ATRIUM_CLI_PATH" pane close  <id>

See the full CLI reference.

Constraints

  • The underlying PTY requires a shell binary (zsh or bash) on $PATH. atrium uses the system default.
  • Very large single-line outputs can stall rendering; use less or redirect to a file for dumps above a few MB.
  • The scrollback persistence format is a VT-escaped grid. Older legacy snapshots without this format are silently discarded on restore.