Terminal interface
orangu is an interactive terminal client with a
persistent header and a prompt area anchored to the bottom of the
terminal.
The individual commands you can type at the prompt are documented in the Core tools, Git tools, and Usage tools chapters. This chapter covers the terminal itself: startup, the header and prompt, sessions, input editing, completion, and scrolling.
Startup
When started inside a Git repository, orangu
fast-forwards the local default branch
(main/master) to origin so it is
in sync with upstream. If you are on the default branch it fast-forwards
your working tree (git pull --ff-only); on any other branch
it fast-forwards the local default ref in place
(git fetch origin <branch>:<branch>) without
touching your current branch or working tree. It never creates a merge
commit or rebases.
The sync runs in the background so it never delays startup. Its
progress and result appear on the left of the status bar —
Syncing with origin… while it runs, then
Synced <branch> with origin (or
Sync failed: …) for a few seconds. It is skipped silently
when there is no origin remote, and a diverged branch or an
unreachable origin is reported only on the status bar;
startup continues normally regardless.
Command-line options
| Short | Long | Description |
|---|---|---|
-c |
--config |
Path to the configuration file. Without it,
./orangu.conf, then
~/.orangu/orangu.conf. |
-w |
--workspace |
Workspace root the local tools operate on. Defaults to
.. |
-r |
--resume |
Resume a stored session by UUID (-l prints them). |
-a |
--all |
Reopen the workspace tabs that were open at the end of the last run. |
-t |
--theme |
Apply a theme to the terminal interface for this run. Built-in names
and paths to .theme files are accepted. |
-p |
--prompt |
Run a single prompt or command and exit — no terminal UI and no session on disk. See One-shot mode below. |
-q |
--quiet |
Print nothing on success — the exit code is the result. Applies to
the modes that print and exit (-p, -l,
-s). |
-l |
--list |
List all stored sessions as a
SESSION WORKSPACE BRANCH DATE table and exit. |
-i |
--init |
Interactively create ~/.orangu/orangu.conf and exit
(see the Configuration chapter). |
-s |
--shell-completions |
Print the shell completion script for the detected shell
($SHELL; bash, zsh, or fish) and exit. |
One-shot mode
-p runs one line and exits, with no terminal interface
and no session on disk. The line is offered to the same parser and
dispatcher the prompt area uses, so it behaves the way it would if you
had typed it:
orangu -p "Hello" # a prompt for the model
orangu -p "/export pr" # a command, run locally
orangu -p "show git status" # the natural-language form of a command
orangu -p "/code-review auth" # a skill, whose expansion goes to the model
A command is handled locally and never reaches the server, so it
works while the model is unavailable. Command output goes to stdout and
a failed command exits non-zero, which makes -p usable from
scripts and from ~/.orangu/schedule. For a prompt, the
answer is streamed to stdout and the timings (total, time to first
token, and the server’s prompt/prefill/decode figures when it reports
them) go to stderr, so orangu -p "Hello" tells a slow
server from a slow prompt.
Two groups of commands are refused rather than run, with a message saying which group they fall in:
- Commands whose only effect is on the running session —
/model,/server,/theme <name>,/verbosity,/disconnect,/reload— since a one-shot exits before the change could matter. Select the server and model inorangu.conf, or point--configat a different file. - Commands that need the terminal interface —
/review,/auto_review,/manual,/pending,/clear,/quit,/restart, and the forms of/workspace,/create_workspace, and/sessionthat switch tab or session. The reporting forms still work: a bare/workspaceprints the active workspace, and a bare/sessionlists the stored sessions.
/export covers the targets that are computed at export
time: pr, statistics, and
duplicates. console, review, and
auto review export what an interactive session accumulated,
and report that there is nothing to export.
Quiet mode
-q prints nothing on success — no answer, no command
output, no diagnostics — and leaves the exit code as the whole result. A
failure still prints on stderr and exits non-zero, so -q
can silence a success without ever hiding a problem:
orangu -q -p "/export pr" # writes the PDF, says nothing
echo $? # 0, or 1 with the reason on stderr
That is what makes it suit a crontab or a
~/.orangu/schedule job: silent until the day it fails. It
applies to the modes that print and exit — -p,
-l, and -s. Combining it with -i
or with the terminal interface is an error rather than a no-op, since
neither has diagnostics to separate from its output.
-t/--theme is the other way round: a theme
paints the interface — including the terminal’s own background and
foreground — so it takes effect only when there is an interface. A
one-shot ignores it rather than repainting the terminal it printed
into.
Header
The top banner displays:
- Current version
- Workspace status
- Server status
- Model status
/helpreminder
While no request is active, server and model status are rechecked once per minute.
The banner is boxed and stays on screen under the default
classic theme, placed by the banner
configuration key. Under theme = modern it is shown
centered on the empty landing screen and gives way to the output window
once the conversation starts. See the Configuration chapter.
Prompt area
The prompt area stays at the bottom of the terminal window.
- The input window carries a bare
>prompt; the branch is not part of it - Below it, the status line shows the current branch on the left,
Graph:andPending:centered, and the active model flush right - Long input wraps upward
- Submitted input moves directly into the output area
- The banner and prompt stay fixed while the output window scrolls independently
- Markdown in assistant output is rendered with terminal styling when possible, including emphasis, strong text, lists, headings, links, and code
- Fenced code blocks with a language tag such as ```c use syntax highlighting in the terminal when the language is supported by the bundled highlighter
All slash commands are handled locally and are never sent to the model, so they continue to work even when the model is unavailable. Free-form prompts, by contrast, are blocked when the server or model status in the header is red.
Waiting state
While the model is generating a response, the left side of the footer shows a rolling:
Thinking (2s)
status indicator.
You can keep typing and submitting commands while a response is pending. Submitted commands are queued and executed in order after the active response finishes.
The footer starts with Thinking (<CLOCK>) and
switches to orangu-server’s native generation throughput
once tokens are streaming, for example
Working @ 42.5 t/s (2s).
Press Esc twice within 2 seconds during the waiting
state to cancel the active request without exiting the client. Queued
commands are preserved.
Sessions
Each run of orangu creates or resumes a session
identified by a UUID. The /session command (see the Core
tools chapter) lists and switches between them; this section describes
how they are stored and resumed.
Automatic resume
On startup, orangu checks whether a session already
exists for the current workspace path and Git branch. If exactly one
matching session with conversation history is found, it is resumed
automatically. The status bar lower-left shows:
Resuming session 550e8400-e29b-41d4-a716-446655440000
for five seconds or until the first command is run. No
--resume flag is needed for normal branch-based
workflows.
If more than one session matches the current workspace and branch, a
fresh session is started instead. Use --resume <uuid>
to target a specific session explicitly.
Manual resume
To resume a specific session regardless of workspace or branch, pass
--resume <uuid> (short form -r) when
starting:
orangu --resume 550e8400-e29b-41d4-a716-446655440000
This restores the previous conversation context and per-session readline history.
Listing sessions
To see every stored session without starting a run, pass
--list (short form -l):
orangu --list
This prints a table of all sessions, newest first, with the columns sized to the widest value in each:
SESSION WORKSPACE BRANCH DATE
550e8400-e29b-41d4-a716-446655440000 /home/user/project main 2026-06-26 11:04
6ba7b810-9dad-11d1-80b4-00c04fd430c8 /home/user/other feature/login 2026-06-26 03:27
The DATE column is the session’s last-updated timestamp
(YYYY-MM-DD HH:MM).
orangu then exits. To list and switch between sessions
from inside a running session, use the /session command
(see the Core tools chapter).
Session cleanup on exit
When you exit, the resume command is printed:
orangu --resume 550e8400-e29b-41d4-a716-446655440000
Sessions that had no LLM interaction (zero tokens generated) and are
on main, master, or a workspace with no Git
repository are deleted automatically on exit. No resume command is
printed for deleted sessions. Sessions on feature branches are always
kept even when empty, so that returning to the branch triggers
auto-resume correctly.
Session storage
Session data is stored under
~/.orangu/sessions/<uuid>/:
history per-session command history (readline)
messages full conversation turn history (JSON array of role/content objects)
metadata session metadata (JSON)
The messages file preserves the complete conversation so
that resuming restores the exact context the model had when the session
was last active.
The metadata file records when the session was created,
last used, which workspace it belongs to, and which Git branch was
active:
{
"started_at": 1748000000,
"last_updated_at": 1748003600,
"workspace": "/home/user/myproject",
"branch": "feature/my-pr"
}branch is an empty string for sessions started outside a
Git repository or in a detached HEAD state. Timestamps are Unix seconds
(UTC).
History and navigation
Command history is stored per session in:
~/.orangu/sessions/<uuid>/history
Use:
<ARROW_UP>to move backward in history<ARROW_DOWN>to move forward in historyCtrl+Rto search backward through history for the last command starting with the letters entered (Tabcompletes it)
Natural-language command aliases
Local commands can also be entered in plain language — for example
open README.md, show status,
create pull request, or
switch model to <name>. The phrases recognized for
each command are listed under its Examples in the Core
tools, Git tools, and Usage tools chapters.
Natural-language forms are recognized only for the built-in local command phrases. Ordinary prompts continue to go to the model.
Comments and ignored input
- If the first non-whitespace character is
#, the line is treated as a local comment, shown in the transcript, and not sent to the LLM - If the first non-whitespace character is
\, the line is ignored
Shortcuts and keys
Prompt editing
Ctrl+AorHomemoves the cursor to the start of the input lineCtrl+EorEndmoves the cursor to the end of the input lineLeftmoves the cursor one character leftRightmoves the cursor one character rightCtrl+Leftmoves one word left using bash-style word boundariesCtrl+Rightmoves one word right using bash-style word boundariesBackspacedeletes the character to the left of the cursorDeletedeletes the character under the cursorCtrl+Dbehaves likeDelete; when the input is empty it exits the client immediatelyCtrl+Kdeletes from the cursor to the end of the lineCtrl+Udeletes from the start of the line to the cursorCtrl+Wdeletes from the cursor to the previous whitespaceCtrl+Rsearches backward through the command history (see below)Alt+Backspacedeletes backward using bash-style word boundariesAlt+Ddeletes forward using bash-style word boundaries- Pasted text is inserted at the current cursor position
History and completion
<ARROW_UP>moves backward through command history<ARROW_DOWN>moves forward through command history- History navigation preserves the current unfinished line as a draft and restores it when you move back out of history
Ctrl+Rsearches the command history backward, like the bash key of the same name, and does nothing when the history is empty:- The last command starting with the letters entered is previewed as
grey ghost text after them, and
Tabcompletes it into the line — the same key that accepts a command hint - The letters already typed are the search, so
carfollowed byCtrl+Rpreviews the lastcargo …command straight away - The status line under the input shows the search prompt, for example
(reverse-i-search)`car': - Typing more letters narrows the search,
Backspacewidens it again Ctrl+Ragain steps to the next older match, skipping repeats of the command on offer; when nothing older matches, the prompt becomes(failed reverse-i-search)`car':and the last match stays on offerEntersubmits the previewed command,Esc(orCtrl+C,Ctrl+G) leaves the search with the line as typed, and any other key — a cursor move, an edit,<ARROW_UP>— leaves the search and acts on the line as typed
- The last command starting with the letters entered is previewed as
grey ghost text after them, and
Inline command hints (ghost text)
As you type, a grey inline hint previews the command your input is growing into, drawn just after the cursor. It covers both slash commands and the natural-language bindings:
- Typing
/qshows/q``uit, withuitgreyed; typingcshowsc``urrent model. - Press
Tabto accept the hint, filling in the rest of the command (for an argument-taking form such asdiff against, the cursor lands after the trailing space, ready for the argument). - When several commands share your prefix (for example
cmatchescurrent model,code review,checkout,commit, and more),Shift+Tabcycles the hint through them in priority order, wrapping back to the first.Tabthen accepts whichever candidate is currently shown. - The hint only appears while the cursor is at the end of the line,
and disappears once your input already spells a complete command (so
statusanddiffshow no hint, even thoughdiff againstshares the latter’s prefix). - Editing the line, moving the cursor, or pasting resets the
Shift+Tabcycle back to the first candidate.
The natural-language hint takes priority over generic filename
completion, so c + Tab completes to
current model rather than a same-prefixed file such as
contrib/. Slash-command and argument completion (branches,
files, commit hashes, and so on) continue to use the cycling
Tab behavior described next.
Tab completion
Tab uses context-sensitive completion. The first
Tab inserts the first match. Repeated Tab
presses cycle through the remaining matches for the same completion
range.
Completion cycling is reset as soon as you edit the line, move the cursor, paste text, or otherwise change the input.
The completion modes are checked in order:
- If the line starts with
/branch,/checkout, or with the natural-language prefixescheckoutorgit checkout, complete branch names first (fromgit branch --all), then workspace file paths. Branch names always appear before file names in the candidate list. If the line starts with the natural-language prefixswitch to, complete branch names and tag names (fromgit tag), sorted together; workspace file paths are excluded. - If the line starts with
/create_file, or with the natural-language prefixescreate,create file,add,add file, orgit add, complete untracked directories first (fromgit ls-files --others --directory), then untracked files. Already-tracked content is excluded. - If the line starts with
/delete_file, or with the natural-language prefixesdelete file,remove,remove file, orgit rm, complete tracked directories first (fromgit ls-files), then tracked files. Untracked content is excluded. - If the line starts with
/move_file, or with the natural-language prefixesmove,move file, orgit mv, complete the first argument from tracked directories and files; complete the second argument from all workspace paths. - If the line starts with
/cherry_pick, or with the natural-language prefixescherry pick,cherry-pick, orgit cherry-pick, complete abbreviated commit hashes from the default branch (origin/main,origin/master,main, ormaster, tried in that order). - If the line starts with
/fetch, or with the natural-language prefixesfetchorgit fetch, complete the configured remotes (fromgit remote), withoriginfloated to the front so the default is offered first and previewed as the inline ghost. - If the line starts with
/rebase, or with the natural-language prefixesrebaseorgit rebase, complete the rebase target in priority order: local branch names first (fromgit branch), then the configured remotes (fromgit remote,originfloated to the front), then the remote-tracking branches (fromgit branch --all, e.g.origin/main). The first local branch is previewed as the inline ghost. - If the line starts with
/merge, or with the natural-language prefixesmergeorgit merge, complete local branch names first (fromgit branch), then remote-only branch names (fromgit branch --all). - If the line starts with
/branch -d, or with the natural-language prefixesdelete,delete branch, orgit branch -D, complete local branch names (fromgit branch) excludingmainandmaster. - If the line starts with
/session(with a trailing space), complete session UUIDs sorted newest-first by last-modified time. - If the line starts with
/model, complete the models available on the selected server, cycling through them. If the line starts with/server, complete the names of all INI sections identified as servers; selecting one switches the active server. - If the line starts with
/open_fileor/show_file, complete workspace file paths recursively for the first positional argument./show_filealso completes--hashand--author. When a file path is already present, the next Tab press cycles through that file’s commit history (abbreviated hashes fromgit log --follow). - If the line starts with the natural-language prefixes
open,open file,edit, oredit file, complete workspace file paths recursively. - If the line starts with
/, complete built-in slash commands and any discovered Agent Skills. Examples include/help,/skills,/model,/server,/list_files,/show_file,/tools,/quit, and a discovered skill such as/debugging. When thedrop_downoption is enabled inorangu.conf(the default), this completion is also visualized as an interactive dropdown menu that intercepts the Up/Down arrow keys. - Otherwise, complete filesystem entries from the current token relative to the workspace, using the token before the cursor.
Path-completion details:
- General filesystem completion lists entries from the matching
directory level and appends
/to directories /open_file,/show_file, and the natural-language open/edit forms search recursively through the workspace- Recursive file completion matches either the full relative path or,
when no
/is present in the token, the file name - Quoted file completion is supported for
/open_file "...",/show_file "...", andopen "..."; the inserted completion keeps the opening quote - Completion skips
.git,build, andtargetcontent - Completion also skips paths ignored by the workspace
.gitignore
Output scrolling
Shift+PageUpscrolls backward through the output window by a full pageShift+PageDownscrolls forward through the output window by a full pageAlt+Upscrolls backward one line at a timeAlt+Downscrolls forward one line at a time- The output scrollback buffer keeps the most recent 10,000 lines
- Scrolling is limited to the output window; it does not replace the header or prompt area
Horizontal panning
orangu maintains a virtual canvas that can be wider than
the visible terminal. Source files shown with /show_file
may contain lines longer than the terminal width; those lines are laid
out on the full virtual canvas and can be panned horizontally without
reflowing.
Alt+Rightpans the output window right (reveals content that extends past the right edge)Alt+Leftpans the output window left (back toward the start of the line)
The header, status bar, and input window always occupy the full visible terminal width and are not affected by panning.
The virtual canvas width is set by the width key in the
[orangu] config section (default 512). When
the terminal is resized to a width larger than the configured virtual
width, the virtual width grows to match so that content is never clipped
unexpectedly. The virtual width never shrinks below its initial value
during a session.
LLM and tool output is always wrapped or clipped to the visible
terminal width and does not pan. Only /show_file output —
where source lines must stay intact — uses the full virtual canvas.
Waiting and exit control
Esctwice within 2 seconds cancels the active request without exiting and keeps queued commandsCtrl+Conce arms quit mode, shows a warning in the transcript, and clears the current input lineCtrl+Cagain within 2 seconds exits the clientEntersubmits the current input line
Built-in manual
Type /manual at the prompt (or the natural-language
forms manual, show manual, or
open manual) to open this manual inside the client. The
manual text is embedded into the binary at compile time, so no external
files are read — the manual is always available, even offline.
The viewer uses the same full-screen, two-pane layout as
/review, with the status bar and an (inactive) input window
kept at the bottom:
- Left pane — the text of the selected section, rendered with the same Markdown styling as model output in the console (bold, italics, headings, lists, links, and tables). Fenced code blocks are shown syntax-highlighted according to their language tag, without the ``` fence lines, and links are shown as their underlined labels only. It is the larger pane and scrolls independently.
- Right pane — the table of contents, one entry per
section. The sections follow the page breaks of the printed manual (one
entry per
\newpage-delimited page): chapter entries are flush left and their sections are indented beneath them. The pane is kept as narrow as possible while still fitting the longest entry. The selected entry is highlighted, and selecting a different entry replaces the left pane with that section’s text, shown from the top.
# Core tools |Contents (56)
|Introduction
The core tools are the local slash |Quickstart
commands that drive the client ... |Core tools <- selected
(only the selected section's text, | /help
scrollable) | /server
Searching
Press Alt+S to open a search window at the top of the
text pane. Type the text to find and press Enter to jump to
its next occurrence: the search is case-insensitive, scans forward from
the highlighted line through the entire manual —
continuing past the end of the current section into the following ones
and wrapping around to the beginning — and highlights the matching line.
Press Enter again to jump to the next instance. If the text
is not found anywhere, No match for '<text>' is shown
on the status bar.
Press Esc to close the search window; the highlighted
line stays on the last match, so you can keep reading from there.
Key bindings
| Key | Action |
|---|---|
Alt+J |
Select the next section (shows its text in the left pane) |
Alt+K |
Select the previous section |
Alt+S |
Open the search window (Enter next match,
Esc close) |
Up / Down |
Move the highlighted line through the text, view following |
Alt+Up / Alt+Down |
Scroll the text one line at a time |
PageUp / PageDown |
Scroll the text by a full page |
Left / Right |
Pan long lines horizontally |
Alt+X or Esc Esc |
Leave the manual and return to the prompt |
Footer behavior
- The left side of the footer shows
Thinking (<CLOCK>)while waiting for a response to start, andWorking @ X.Y t/s (<CLOCK>)while tokens are streaming - The center side of the footer shows
Pending: Xto show how many queued commands are waiting - The right side of the footer shows the model name used