> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orchestrahq.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Terminal client

> One terminal UI to start any supported agent on a task, find and pick up any session you can see, and search everything, with teammates' messages arriving while you type

Run `orchestra` with no arguments and you land on home: a prompt, and below it
the workspace's sessions, grouped by what you can do with them: **Running**,
**Paused** (type to resume one here), and **History**, which stays one line with
a count until you open it. The count is every session you can see, including the
ones home has not loaded yet: home reads 60 at a time, and when there are more, the
last row of an open history is **More**, which reads the next 60.

## Start a session in one keystroke

The first row of home is **New session**. When nothing is running, it is
highlighted, so `orchestra` then Enter starts a session on Claude Code (or the
first agent that can start on your machine) in the current folder, waiting for
your first message. When something is running, the highlight starts on that
session instead, and **New session** is one `↑` away.

The row says who will see the session before you start it: your workspace, by
default. Press `ctrl+p` first to make it private, so only you see it, from its
first event. The row, the **start a new task** row and the `ctrl+n` picker all
say which it is, and the choice holds for the rest of that terminal session.
A session started from here is run by Orchestra, so it cannot be off the
record; for that, use `orchestra start --off-record` (see
[Session privacy](https://docs.orchestrahq.ai/session-privacy.md)).

Home is a picker. Type to filter: sessions that don't match disappear, history
included. `↑` and `↓` move the highlight (`tab` and `shift+tab` too, `←` and `→`
while nothing is typed, `PgUp`/`PgDn` a page at a time), and Enter opens the highlighted session. While you type, the
list ends with two more rows: **search messages** for what you typed, then
**start a new task** with it. If no session matches, the search comes first, so
Enter searches the messages, decisions and issues you can see (`ctrl+f` does the
same from anywhere). Starting an agent is one `↓` away, or `ctrl+n`, which also
lets you pick the agent, model and folder yourself. A new task starts on Claude
Code, or the first agent that can start on your machine, with what you typed as
its first message. `esc` clears the filter, and so does `ctrl+c`; on an empty
input, `ctrl+c` twice quits. Whatever a teammate types in the
browser shows up in your terminal while you are typing.

Each session has a short ref, like `S-12`, numbered in the order sessions were
created in the workspace, so two sessions with the same title are never
confused. A row shows the ref, the session's name (or its title), the git
branch it is on, then the agent, what a running agent is doing right now, who
started it and when. Filter by any of them: `S-12`, a branch, an agent, a name.

```sh theme={null}
orchestra                 # home
orchestra tui S-12        # straight into a session by its ref
orchestra tui 5430d885    # or by its id (the short id works)
```

## In front of your terminal

Orchestra draws in your terminal's alternate screen, the way `vim`, `less`,
`htop` and Claude Code's fullscreen mode draw. A session fills the window: the
transcript above; at the bottom, a status line when there is something to say,
the input between two rules with a `❯` prompt, as in Claude Code, and one footer
line with what the session is and the keys. The input never moves. It
stays put while a reply streams in, when you resize the window, and while you
scroll back.

* **Scroll** with the mouse wheel or trackpad, or `PgUp` and `PgDn`. The whole
  session is there, back to its first message. Scrolled up, what you are
  reading holds still while new output arrives below it, and a **Jump to bottom**
  button appears above the input, saying how far below the live end you are.
  Click it, scroll down, press `PgDn`, or send a message to get back.
* **Copy** by dragging over the transcript. Releasing copies the selection to
  your clipboard (over SSH, through your terminal, with OSC 52). Holding your
  terminal's selection modifier (`option` in iTerm2, `shift` in most others)
  still gives you the terminal's own selection.
* **Leave** with `ctrl+c` twice (once clears what you typed, as in Claude Code). Home comes back clean, with nothing of the session
  left on screen. **Quit** with `ctrl+c` twice on home, and your terminal is exactly
  as it was before you ran `orchestra`. Orchestra never erases your scrollback.

Your terminal's own find (`cmd+f`) searches only what is on screen. To find
something in a session's history, use `ctrl+f` on home (it searches every
message you can see), or scroll. The transcript is not left in your terminal
after you quit; `orchestra tui S-12` reopens it with its whole history.

Your terminal is restored however Orchestra exits: quitting, `ctrl+c`, the
window closing, a `kill`, or a crash, and mouse reporting is switched off with
it. Only `kill -9` can't be caught; if that leaves a blank screen, run `reset`.

The alternate screen is used only on an interactive terminal. Piped output,
`TERM=dumb` and CI get none, and `ORCHESTRA_ALT_SCREEN=0` turns it off. Without
it, a session prints into your terminal's normal scrollback instead, so the
terminal's own scrolling, find and selection cover it and it stays after you quit,
but the input is no longer pinned, and a long session prints only its newest 200
items. GNU `screen` ignores the alternate screen unless `altscreen on` is in your
`.screenrc`; `tmux` honours it by default.

## Tabs

Every session you open in a run stays open as a tab. With two or more open, a
strip along the top shows them all by ref and name, and what each one is doing:

```
 S-12 auth retry ⠙ │ S-14 web nav ● │ S-15 lexer │ S-9 deploy ended
```

A spinner means its agent is working, `●` means something happened since you
last looked, and `ended` means the session is over. `←` and `→` (while the input
is empty) or `tab` and `shift+tab` move to the previous and next tab. Switching is instant, and each tab keeps its
draft and where you had scrolled to. `ctrl+c` goes home with your tabs still
open; opening a session that already has a tab goes straight to it.

**Closing a tab** never stops anything: the agent keeps running and home still
lists the session. Click a tab's `×`, or press `ctrl+d` on an empty input. Click
a tab's name to switch to it.

**Stopping an agent** is a separate, deliberate step. In a session, `/stop` asks
once, naming anyone else in it, and the second `enter` ends the run. On home,
`ctrl+x` on a running session asks "press ctrl+x again to stop", and the second
press stops it. Either way the session stays open, with its history, and
`ctrl+r` resumes it. Only the terminal running a session can stop it; anywhere
else, `/stop` is listed with that reason.

## The greeting

Home opens with the Orchestra wordmark in block letters, in the brand indigo,
with the mark standing in for the "O". Below it is what is worth knowing before
you start:

```text theme={null}
Ada in ~/code/acme  v0.1.0 · 872f8ad
● Priya S. and Arnav live now
! capture failed here 2h ago · orchestra doctor
```

* **Who is live** is read from the session list. It stays blank until the
  list has loaded, so it never shows a guess.
* **A `!` line** means something is wrong in the repo you are in. Today that
  is a failed capture (the same warning your agent's session gets), and the
  line says what to run.
* **A `↑` line** means a newer Orchestra is available, with the command to
  upgrade.

The greeting fits itself to the terminal, always leaving at least four rows
of sessions below the prompt:

* **77 columns or wider:** the full banner, when its rows fit.
* **Narrower or shorter:** the mark on its own as a small ring of dots, with
  those lines beside it.
* **Shorter still, and on every later visit to home:** a single line with the
  wordmark, the version and the first notice.

Nothing animates.

The colours are Orchestra's. The mark and wordmark use the logo's light or dark
colours, whichever matches your terminal's background. The rest of the client
uses the product palette the web app uses: accent, live and warning. The
client draws them at the colour depth your terminal supports.

| Variable | Effect |
| - | - |
| `NO_COLOR` | No colour anywhere the client draws through its palette, the greeting included. |
| `FORCE_COLOR` | `0` to `3` overrides the colour depth the client detects (none, 16, 256, 24-bit). |
| `ORCHESTRA_THEME` | `light` or `dark`. Otherwise the client asks your terminal for its background color when it starts, and uses `COLORFGBG` if the terminal does not answer. |
| `ORCHESTRA_MARKS` | `icons`, `glyphs` or `plain`: each agent's logo, a character, or the name alone. Otherwise the client shows logos when the Orchestra Symbols font is installed, and characters when it is not (see [Agent logos](#agent-logos)). This is the environment form of the `marks` setting, which a settings file can hold too (see [Settings](https://docs.orchestrahq.ai/settings.md)). |
| `ORCHESTRA_NO_UPDATE_CHECK` | `1` turns the update check off. |
| `ORCHESTRA_ALT_SCREEN` | `0` draws in your terminal's normal buffer instead of in front of it: sessions print into its scrollback, with no pinned input, wheel scrolling or tabs. For a terminal that misbehaves with the alternate screen, or if you prefer native scrollback. |

Piped or scripted, `orchestra` prints its help as plain text, with no greeting
and no escape codes.

## What it is, and what it is not

Orchestra runs the agent headless behind a **launch adapter**: Orchestra owns
the session (the input, the rendering and the event log), and the vendor owns
the agent (the loop, the context, the tools and the permissions). It is a
client, not a competing agent. The two never fight over one terminal, and a
teammate's message can land in an input box Orchestra owns.

## Agents

| Agent | Status | Runs on |
| - | - | - |
| Claude Code | ready | Your installed `claude`, with your login, CLAUDE.md, settings and MCP servers |
| Orchestra | ready | The same agent loop on the Agent SDK's bundled Claude, for machines without Claude Code installed |
| OpenCode | ready | `opencode serve`, started headless, using your OpenCode providers and logins |
| Codex, Gemini CLI | soon | Listed in the picker, dimmed, as not yet available to start |

### Agent logos

Wherever sessions are listed, each agent's name follows its logo, both in the
agent's own colour, so you can tell agents apart without reading. An agent
that can't be started yet keeps its logo, dimmed, and says "soon".

The logos come from a small font, Orchestra Symbols. Install it once:

```bash theme={null}
orchestra font install
```

Your terminal font stays as it is. When your font has no logo for an agent,
the terminal finds it in Orchestra Symbols, so you don't need to change any
terminal setting. Restart a terminal that was open during the install.
`orchestra font remove` uninstalls it, and `orchestra font status` (or
`orchestra doctor`) shows whether it is installed and what this terminal will
show. The font installs for you alone, without an administrator, on macOS and
Linux. It can't be installed on Windows yet.

Without the font, each agent gets a character instead: ✻ Claude Code, ⦿
Orchestra, ▮ OpenCode, ❀ Codex, ✦ Gemini CLI and ⬢ Cursor. A terminal that
isn't set to UTF-8, or the Linux console, shows the names alone.

Over SSH, the font that draws the logos is the one on the computer in front of
you, which the client can't check. It shows characters there unless you set
`ORCHESTRA_MARKS=icons`, or `"marks": "icons"` in `~/.orchestra/settings.json`
(see [Settings](https://docs.orchestrahq.ai/settings.md)).

Claude Code and Orchestra need Claude credentials: either a signed-in Claude
Code (`claude auth login`) or an `ANTHROPIC_API_KEY`. A Claude Code login is
enough on its own; you don't need an API key.

The picker only lets you choose an agent that can actually start here and now.
For example, Claude Code with no `claude` on `PATH`, or OpenCode with no
`opencode` binary, says why it can't start and can't be selected.

A Claude Code session started here is named by Claude Code. It starts as
`Claude Code in <folder>`, and once the first turn ends it takes the title
Claude Code generated for it, the same name it would have in Claude Code
itself. If Claude Code renames it later, the new title follows. A session that
already has a name keeps it: one you named, one opened for a work item, or one
you continue.

Claude Code still writes its transcript to `~/.claude/projects`, because that
is where it puts the title. Orchestra marks the session as its own before it
starts, so your capture hooks, `orchestra watch` and `orchestra doctor` all
skip it. The session is already recorded in Orchestra, so it is never captured
a second time.

For OpenCode, name the model as `provider/model`, for example
`openai/gpt-4.1-mini`. Leave it blank to use OpenCode's default. A launched
OpenCode server gets a random password so no other local process can drive it.
It also keeps its sessions under `~/.orchestra/opencode` rather than your own
OpenCode store, so the capture watcher doesn't record the same session twice.
Your provider logins are linked through, not copied.

## In a session

The line above the input says what the session is and whether your words reach
the agent. The input's prompt says where they go: `›` to the agent, `note ›`
to your teammates. When the agent can't hear you, the reason and what you can
do instead are right there.

| The session is | Above the input | Prompt | What you can do |
| - | - | - | - |
| Running in this terminal | Running here | `›` | `esc` interrupt · `ctrl+c` end it |
| Running in a teammate's Orchestra | Running in Priya's terminal | `›` | `esc` interrupt |
| In a teammate's own Claude Code, with Orchestra's hooks | In Priya's Claude Code · messages arrive after its current step | `›` | only Priya can stop it |
| In a teammate's own agent, without the hooks | In Priya's Claude Code · it can't see messages from here | `note ›` | `ctrl+r` continue it here |
| Nothing is running it | Paused · nothing is running it | `›` | type to resume it here · `ctrl+r` resume now |
| Finished | Finished | `note ›` | `ctrl+r` continue it here |

| Key | Does |
| - | - |
| `enter` | Send. To the agent when the prompt is `›`, as a note to teammates when it is `note ›` |
| `/note <text>` | Leave a note for teammates even when the agent can hear you. The agent never sees it |
| `!<command>` | Run a shell command in the session's folder, as the agent's own shell mode does. See [The agent's own shortcuts](#the-agents-own-shortcuts) |
| `↑` / `↓` | Recall your earlier messages in this session (in a multi-line draft, move between its lines first). They never scroll |
| wheel, `PgUp` / `PgDn` | Scroll back through the session, to its first message |
| drag | Select transcript text; releasing copies it |
| `←` / `→`, `tab` / `shift+tab` | The previous or next open tab (the arrows while the input is empty; with text, they move the cursor) |
| `ctrl+d` | On an empty input: close this tab. The session keeps running |
| `/stop` | Stop the agent running this session, after one confirm. The session stays open; `ctrl+r` resumes it |
| `\` then `enter`, `option+enter`, `ctrl+j` | Start a new line in the message instead of sending it. Long lines wrap at word boundaries, and the input box grows with the message, up to 8 rows |
| paste | Up to three lines, or one line up to 800 characters, goes in as typed. Anything longer shows as `[Pasted text #1 +9 lines]` (or `[Pasted text #1]`) and is sent in full. Paste the same text again to expand it in place; `backspace` removes the whole paste |
| `ctrl+v` | Paste an image from the clipboard (a screenshot, a copied picture). It shows as `[Image #1]` and `backspace` removes it whole. Dragging an image file into the terminal attaches it the same way. Claude Code and OpenCode sessions running in this terminal see the picture itself. Anywhere else, the agent gets the image's file path on this machine. `alt+v` does the same where the terminal keeps `ctrl+v` for itself. On Linux it needs `wl-paste` (Wayland) or `xclip` (X11) |
| `esc` | Interrupt the running turn. Your own turn stops at once; stopping a turn someone else asked for takes a second `esc`, behind a line that names them. With nothing running, `esc` twice clears what you typed |
| `ctrl+r` | Resume a paused session here, or continue someone else's (or a finished one) as your own |
| `ctrl+o` | Expand tool output and thinking in place, all the way back; again to collapse |
| `ctrl+c` | With text typed, clear it. On an empty input, press it twice to leave for home, as Claude Code asks twice to exit. Nothing stops: an agent running here keeps running on this machine, and its tab stays open |

Agent replies render their markdown: `inline code`, **bold**, *italic*, lists,
headings, links (with the URL shown), tables aligned into columns, and fenced
code blocks with light syntax colour. Your own messages are shown exactly as you
typed them. Tool calls print as one line each. An edit also shows its diff, the
lines it removed and added with their line numbers, without a keypress, up to
40 rows. Under a longer one, a line says how many lines are left and that
`ctrl+o` shows them. The `diffs.show` and `diffs.maxLines` settings turn this
off or change the cap (see [Settings](https://docs.orchestrahq.ai/settings.md)).

**Resuming a paused session.** When no run of an Orchestra session is open,
nothing is running it, and home lists it under Paused. Type to it as usual: the first
Enter asks once, naming the agent and folder, because its tools will run as you
on your machine. The second Enter resumes it here, on its original agent, with
its history replayed, then delivers your message. Slash commands work the same
way, and `ctrl+r` resumes it without a message. The history is rebuilt from the
log, not an exact resume of the earlier process.

**A teammate's own agent.** A Codex or Cursor session running in someone's own
terminal can't read anything Orchestra writes, so what you type is a note to
teammates: they see it, attributed, and the agent never does. Slash commands
are refused there.

A Claude Code session started by hand in a repo where `orchestra enable` has
run is different: its hooks hand your message to the agent **after its current
step** (or with the next prompt its owner types, whichever comes first). Your
line shows `(waits for its current step)`, and when the hooks hand it over a
line follows: `your message reached the agent`. Delivery is between steps,
never mid-step; the owner's keyboard is the only one in that terminal; and
`esc` can't stop it from here, only its owner can. The owner sees every
delivery on their own screen. A session stays reachable however long its
agent is quiet, as long as its owner's machine keeps reporting that the agent
is running. If the agent stops without exiting, or its machine stops reporting
for ten minutes, messages to it stop, and the line above the input says which. If its owner runs
`orchestra disable`, the line says they turned messages off, and what you type
becomes a note to teammates.

Either way, `ctrl+r` **continues it here**: Orchestra forks it into a new
session on this machine, with its history, and switches you to it (type a first
message before pressing Enter if you like). The original is left exactly as it
was. To let teammates message a session from the start, begin it from
`orchestra` instead of running `claude` yourself.

## Slash commands

Type `/` and a menu of commands opens above the input, as in Claude Code. Keep
typing to narrow it: names that start with what you typed come first, then names
that contain it. `↑` and `↓` move the selection, `tab` completes the name, and
`enter` runs a command that needs nothing more, or completes one that takes
arguments so you can type them. `esc` closes the menu. A command this session
can't run is still listed, with the reason after its description.

After Orchestra's own commands, the menu lists the agent's: for Claude Code,
its built-in commands (`/compact`, `/context`, `/init`...), your skills and your
project's commands; for OpenCode, its commands. The list is the one the agent
gave the last time it ran on this machine until the running agent sends its own,
a few seconds after it starts. Picking one sends the line to the agent as you
typed it, and the agent runs it. They need the session to be running; when
nothing is, they stay listed with that reason. Where a name is both
Orchestra's and the agent's (`/model`, `/clear`), Orchestra's runs, so everyone
in the session sees the change.

Once you type a command's name and a space, what it takes appears greyed out
after it, as in Claude Code: `/compact  <optional custom summarization
instructions>`, `/note  <text>`. It goes as soon as you start typing the
argument. `/model` shows the model the session is on now, and `enter` on it opens
a picker with the agent's own list of models (for Claude Code, the same list its
own `/model` shows), with ✔ on the current one. `↑` and `↓` or a number choose,
`enter` switches the session to it for everyone, `esc` cancels. An agent that
doesn't list its models takes the model id typed after `/model`.

Slash commands follow one contract, shared by the terminal and the web
composer, so they mean the same thing in both places.

| Command | Effect |
| - | - |
| `/model <id>` | Switch the session's model for everyone in it |
| `/clear` | Start the agent's context fresh for everyone. If anyone else has been active in the session in the last 15 minutes, it asks first and names them |
| `/help` | List the commands |

A command is a change to the session's state, not a message. It is recorded as
its own attributed event and shown to everyone as a system line, such as
"Priya switched the model to openai/gpt-5-nano". A command neither Orchestra
nor the agent recognizes is refused, and nothing is sent. To send a message that starts with a
slash, begin it with `//`.

## The agent's own shortcuts

What you type means what it means in the agent's own terminal. A Claude Code
session takes Claude Code's shortcuts, and an OpenCode session takes OpenCode's.
Neither gets the other's.

**`!` runs a shell command.** Start a line with `!` and the rest runs in your
shell (`$SHELL`) in the session's folder, as you, on your machine. While you type
it, the input turns amber and says where it will run. `esc` stops a command that
is still running, and a command stops on its own after two minutes. Only a `!` in
the first column counts, so a line that starts with a space is a message. What
happens to the output follows the agent:

| Agent | The output |
| - | - |
| Claude Code, Orchestra | Goes to the agent at once, in Claude Code's own form, and the agent answers it. If your Claude Code settings have `"respondToBashCommands": false`, it waits and goes with your next message instead |
| OpenCode | Shows here and goes with your next message, so the agent reads it without a turn of its own |

Only the terminal running the session runs `!` commands for it. In a session
running in a teammate's terminal, or a session captured from someone's own
tool, `!` is refused with the reason and nothing runs. Everyone in the session
sees the command and its output once it reaches the agent.

**Commands only Claude Code's own screen has.** Orchestra runs Claude Code without
its screen, so commands like `/permissions`, `/login`, `/logout`, `/hooks`,
`/memory`, `/theme`, `/status`, `/plugin`, `/ide`, `/doctor` and
`/terminal-setup` would otherwise do nothing. Picking one hands the terminal to
Claude Code, opened on that command in the session's folder. When you quit it,
the terminal comes back to the session as it was. That screen is off the record:
it is not saved as a session. It needs Claude Code installed on this machine and
the session's folder to be here. The menu lists these with what each does.

**Commands that can't run here.** A few of Claude Code's commands work on its
private copy of the conversation, which Orchestra runs without its screen:
`/rewind`, `/fork`, `/export`, `/add-dir` and similar. They are refused with the
reason, and where there is an Orchestra way to do the same thing the message
names it. The same goes for OpenCode's `/undo`, `/redo` and `/share`.

**Leaving and switching.** `/exit` and `/quit` leave the session, which keeps
running, as `ctrl+c` does. `/resume` goes home, where your sessions are listed.
On OpenCode, `/sessions` does the same.

Codex and Gemini CLI have no launch adapter yet, so a session of theirs can only
be watched here, and none of their shortcuts apply. Type them in that tool's own
terminal.

## Streaming

Replies stream in word by word as the agent writes them. A tool call shows its
name and what it is running while it runs, and its result when it finishes.
`ctrl+o` expands every tool call's output and thinking in place, including ones
you have scrolled past. Streamed text is shown live but is never written to the
log; only the finished message becomes an event, so the browser and the
terminal record the same thing.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.