Skip to content

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

FlagDefaultMeaning
--format <fmt>textOutput format: text or json
--jsonShortcut for --format json
--no-headersDrop table headers from text list output
-q, --quietSuppress non-essential success output
--socket <path>autoOverride the runtime control socket path
--config-file <path>autoOverride the config file path
--timeout <ms>3000IPC timeout when talking to the running app
-y, --yesSkip destructive-action confirmation prompts
--versionPrint version and exit
-h, --helpHelp 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"
FlagMeaning
--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 right

view opens read-only; edit opens in edit mode. <target> is a file path or an http(s) URL. Both accept the same flags:

FlagMeaning
--mode <view|edit>Override read-only vs. edit
--new-tabOpen in a new tab (default placement)
--new-windowOpen in a new window
--left, --right, --top, --bottomSplit 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 app

Some 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)
--monospaceMonospace families only
--system / --userOnly 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 --activate

list 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 badge

Common 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 test

Wraps 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.

FlagMeaning
-q, --quietSuppress 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 -v

Blocks 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.

FlagDefaultMeaning
--interval-ms <n>5000Poll interval in milliseconds
--timeout-secs <n>0Overall timeout; 0 waits forever
--unknown-timeout-secs <n>60Give up after this long with no state reported at all; 0 waits forever
-v, --verbosePrint 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 path

Sends 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 command

ignore 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 import

Imports 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
FlagMeaning
-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 sheet

Renders 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 $TERM

Otty 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 invocation

Prints 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.fish

Settings → 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

Otty