Appearance
CLI Reference
Complete reference for the otty command-line tool. For scenario-oriented examples see Using the CLI in your Shell.
bash
otty <subcommand> [flags] [args]Running otty with no subcommand (or starting with -e) launches the GUI, so otty and otty -e <cmd> behave like xterm / alacritty / ghostty. Many subcommands that inspect or drive the UI (window, tab, pane, view, edit, jump, …) require a running Otty app.
Global flags
| Flag | Default | Meaning |
|---|---|---|
--format <fmt> | text | Output format: text or json |
--json | — | Shortcut for --format json |
--no-headers | — | Drop table headers from text list output |
-q, --quiet | — | Suppress non-essential success output |
--socket <path> | auto | Override the runtime control socket path |
--config-file <path> | auto | Override the config file path |
--timeout <ms> | 3000 | IPC timeout when talking to the running app |
-y, --yes | — | Skip destructive-action confirmation prompts |
--version | — | Print version and exit |
-h, --help | — | Help for the current command |
Subcommands
otty open [path] — open a new window
bash
otty open # new window
otty open ./projects # new window in a directory
otty open --command "vim" --title "Editor"| Flag | Meaning |
|---|---|
--command <cmd> | Run a command in the new window |
--title <title> | Window title |
otty view <target> / otty edit <target> — open a file or URL as a pane
bash
otty view ./README.md # read-only
otty edit src/lib.rs # editable
otty view https://docs.otty.sh
otty view --right tail.log # split to the rightview opens read-only; edit opens in edit mode. <target> is a file path or an http(s) URL. Both accept the same flags:
| Flag | Meaning |
|---|---|
--mode <view|edit> | Override read-only vs. edit |
--new-tab | Open in a new tab (default placement) |
--new-window | Open in a new window |
--left, --right, --top, --bottom | Split the focused pane in that direction |
otty config get/set/unset/edit/... — manage configuration
bash
otty config get theme
otty config set theme dracula
otty config set theme dracula --reload # also reload the running app
otty config set font-size 14 --transient # running app only, don't persist
otty config unset font-size
otty config edit # open in $EDITOR
otty config show # print normalized config
otty config path # print the config file path
otty config validate # check for errors
otty config reload # reload in the running appSome settings hold a list — environment variables, CLI aliases, font fallbacks, launch profiles. config get prints one entry per line, and config set takes the whole list back. To change one entry without restating the rest, sign it:
bash
otty config set env +EDITOR=nvim # add, or replace the EDITOR entry
otty config set env -EDITOR # remove, by name or by whole entry
otty config set font-family-fallback "+Noto Color Emoji"Sign every entry or none — a value mixing the two is rejected rather than guessed at. config set prints the resulting list, so you can see what the edit produced. To store a value that itself starts with + or -, use otty config edit.
See the Configuration Reference for every key.
otty font list / apply / import — manage fonts
bash
otty font list --monospace
otty font apply "JetBrains Mono" # writes font-family to config
otty font import ./MyFont.ttf --apply # copy into ~/.config/otty/fonts/Flag (on list) | Meaning |
|---|---|
--family <name> | Filter by family (substring) |
--monospace | Monospace families only |
--system / --user | Only system-wide / only user-supplied fonts |
otty theme list / import — manage color themes
bash
otty theme list --color dark
otty theme import https://themes.otty.sh/nord.toml --activatelist filters with --color <dark|light|all> (default all). import takes a local path or URL — an Otty .toml, an iTerm2 .itermcolors, or a kitty / alacritty / ghostty color file — and accepts --activate (switch to it) and --overwrite (replace a same-named theme in place). To switch the active theme without importing, use otty config set theme <name>.
otty keybind list — list keybindings
bash
otty keybind list
otty keybind list --action split # filter by action name (substring)See the Keybindings Reference for the defaults.
otty window / tab / pane — drive the running app
Inspect and manage windows, tabs, and panes in a running Otty (the plural forms otty windows / otty tabs / otty panes are shortcuts for … list).
bash
otty panes --json
otty tab new --command "cargo watch" --title build
otty pane split --direction right --command "htop" --size 30 # --size = the NEW pane's share, 10–90
otty pane resize --right 10 --down 5 # move this pane's dividers, in cells
otty pane send-keys --pane 3 -- "echo hi" key:Enter
otty pane capture --pane 2 --lines 50
otty tab badge --kind running # set a tab status badgeCommon subcommands across the three: show, list, new, close, focus, rename (window/tab), move (tab). Panes additionally have split (--direction right|left|up|down), zoom, resize, send-keys, send-text, run, exec, wait, and capture. Badge kinds are running, completed, finished, unread, error, awaiting-input.
A --pane / --tab selector takes an id or index; a non-matching selector fails with No pane/tab matched selector (exit 4) rather than falling back to the active one. To target the pane a script is itself running in — instead of the focused pane — pass the $OTTY_PANE_ID variable Otty exports into every pane: otty pane show --pane "$OTTY_PANE_ID". See $TERM and Identification.
otty watch <cmd> — run a command with a progress badge
bash
otty watch make deploy
otty watch -q cargo testWraps cmd so the tab shows a spinner while it runs and a success / error badge when it exits (via OSC 9;4), then posts a Notify on Watch Finish notification. See Progress State.
| Flag | Meaning |
|---|---|
-q, --quiet | Suppress the system notification on finish |
otty watch:<agent> <id> — block until an agent is idle
bash
otty watch:claude 9f3c1a2b
otty watch:codex <id> --timeout-secs 600
otty watch:opencode <id> --interval-ms 2000 -vBlocks until the named code-agent session (claude / codex / opencode) reaches the idle state, then exits — for orchestrating one agent against another. Exit 0 on idle (or if the session has since closed), 4 if the session never reported a usable state, 6 if the agent has no integration installed, 9 on timeout.
| Flag | Default | Meaning |
|---|---|---|
--interval-ms <n> | 5000 | Poll interval in milliseconds |
--timeout-secs <n> | 0 | Overall timeout; 0 waits forever |
--unknown-timeout-secs <n> | 60 | Give up after this long with no state reported at all; 0 waits forever |
-v, --verbose | — | Print state transitions to stderr |
Only hooks report state
The state this waits on comes from the agent's own lifecycle hook, so without the integration installed the session can never report anything and the wait would never end. The command detects that and exits 6 immediately rather than hanging. Hooks are read at session start, so after installing them you must restart the agent session — a session already running keeps reporting nothing, and --unknown-timeout-secs is what stops the wait in that case (exit 4).
otty jump [query] — jump to a frecency-ranked directory
bash
otty jump otty # cd the focused pane to the best match
otty jump # toggle between $HOME and the last jump source
otty jump otty --no-cd # just print the resolved pathSends cd <path> to the focused pane. --no-cd resolves only and prints the path, so a shell wrapper can cd locally. See Open Quickly & Jump.
otty learn [path] / otty ignore <path> — teach the frecency database
bash
otty learn ./projects/otty # record a directory visit
otty learn # record the focused pane's cwd
otty ignore ./old-project # forget a directory or learned commandignore is the undo of learn.
otty import <source> — import from other terminals
bash
otty import zoxide # merge zoxide frecency
otty import ghostty # ~/.config/ghostty/config
otty import kitty ./kitty.conf
otty import alacritty
otty import theme ./nord.toml --activate
otty import https://example.com/MyFont.ttf # auto-detected → font importImports another terminal's config (ghostty / kitty / alacritty), zoxide frecency, or a theme. External-config imports accept --overwrite and --keep. A bare otty import <path-or-url> auto-detects: font files route to font import, theme files to theme import.
otty export <target> — export your config to another terminal
bash
otty export ghostty # to stdout
otty export kitty -o kitty.conf
otty export alacritty -o alacritty.toml| Flag | Meaning |
|---|---|
-o, --output <path> | Write to a file instead of stdout |
otty features [name] — try terminal feature samples
bash
otty features list
otty features true-color # shorthand for `otty features try true-color`
otty features unicode # i18n / complex-script smoke sheetRenders self-contained demos for colors, styles, emoji, CJK / RTL / Thai & other international text, box-drawing, OSC sequences, images, and more. Run otty features list for the full catalog; unicode is a one-shot sheet for eyeballing complex-script shaping, combining marks, East-Asian width, emoji clusters, zero-width and astral-plane code points.
otty ssh terminfo <host> — check a remote for a shadowing terminfo entry
bash
otty ssh terminfo myserver # report only
otty ssh terminfo --clean myserver web1 # move the shadowing entries aside
otty ssh terminfo --term xterm-ghostty box # check a name other than your $TERMOtty 1.3.0 and earlier could install a copy of your Mac's terminfo description into ~/.terminfo on hosts you ran remote commands against, where it shadows the distribution's own, more complete entry. This finds those and prints exactly what changes if one goes — which capabilities come back, and which values differ (kbs, the Backspace key, is a common one).
--clean moves the entry into ~/.terminfo-otty-backup on the remote rather than deleting it, and asks first unless you pass --yes. A host whose only entry for that name is the one in ~/.terminfo is never touched: that is the terminfo install working as intended.
otty ssh doctor <host> — explain what the SSH integration does for a host
bash
otty ssh doctor myserver
otty ssh doctor myserver --json
otty ssh doctor myserver -- -F ./config -o ControlMaster=no # diagnose an exact invocationPrints what Otty's ssh wrapper decides for that host and why: what your ssh config resolved to, whether Otty honors a ControlPath you configured or mints its own, which login shell answers on the far end (a non-POSIX one such as fish changes what a remote command may look like), and whether the terminfo probe succeeds. Everything the wrapper does happens on a machine Otty does not control and degrades quietly when it goes wrong, so this is the thing to paste into a bug report.
Nothing is written on your behalf and no state is kept between runs — the answer is recomputed from your config each time.
otty completions <shell>
Prints a shell completion script to stdout. Supported shells: bash, zsh, fish, elvish, powershell.
bash
otty completions zsh > "${fpath[1]}/_otty"
otty completions fish > ~/.config/fish/completions/otty.fishSettings → Shell → Install CLI installs these for you. See CLI Usage → Install the CLI.
otty version
Prints version, build hash, and a brief feature/protocol summary.
Hooks & integrations
otty state:<agent> key=value … reports a code-agent's lifecycle state and otty ipc <command> sends a raw control message. These are invoked by Otty's bundled agent hooks and shell integration, not typically by hand. See Multi-agent integration.
state: accepts any agent name, which is how a third-party agent integrates itself without a built-in adapter — see Custom agents for the arguments and what they light up.
See also
- Configuration Reference — every option you can set in config.
- Keybindings Reference — the default key map.
- CLI Usage — task-oriented examples.