The CLI · Rex Docs

The CLI

rex is the command-line interface to Rex.

rex is both an administrative tool for Rex as well as a foundation for automation. As an administrative tool, it can create sessions, split panes, list active clients, force disconnect a client, etc. As an automation tool, it has a complete, powerful Lua scripting interface.

Rex adds rex to the PATH of every terminal it opens, and sets up the context so that the CLI already knows what session you’re in, which block you’re looking at, and so on.

If rex isn’t found, see PATH.

Open a terminal and try it:

rex ls                 # list your sessions
rex session inspect    # show details of the session you are in
rex block inspect      # show details of the terminal you are typing in

Run rex help for every command, or rex help <command> for the details of one.

Taxonomy

Rex organizes work into four kinds of things. Every command acts on one or more of them.

Each one has an ID that never changes and is never reused, such as block:01a10d99-0c06-7795-bf67-798ce4c36a33. Sessions, windows, blocks, and clients can also have a label, which is a name you choose and can change.

Command Targets

With no options, a CLI command acts based on its context. Inside a Rex terminal that is the terminal’s own block and session, so rex split splits the terminal you typed it in. Rex knows where you are from three environment variables it sets in every terminal:

Variable Holds
REX_SESSION The ID of the session the terminal belongs to
REX_BLOCK The ID of the terminal’s own block
REX_SERVER The address of the server that runs the terminal

To act somewhere else, specify it with a flag:

Option Chooses
-s, --session A session
-w, --window A window within the session
-b, --block A block
-C, --client A client. REX_CLIENT sets a default.
-S, --server A server, by the label of a host from rex hosts or by address. REX_SERVER sets a default.
rex send -s build -w 2 'make test'   # type into window 2 of the "build" session
rex capture -b logs                  # print the screen of the block labeled "logs"
rex -S studio ls                     # list the sessions on the host labeled "studio"

Targets

Rex tries to match a session, window, block, or client target (such as -C) in this order and stops at the first kind of match it finds:

  1. A full ID, such as session:01a10cf3-2655-7e48-9b9c-43dd6612bef5.
  2. A case-insensitive label, such as build.
  3. A position, counting from one. Windows are numbered in tab order, so -w 2 is the second tab.
  4. The end of an ID, at least four characters long, such as 12bef5. Listing commands print these short IDs.

If a target matches more than one thing, the command stops without changing anything, lists what matched, and exits with status 3:

Error: session target "work" is ambiguous
  first   …001234
  second  …00abcd

A server is the exception. -S takes only a host label or an address, and a value with a port is always an address.

Labels are convenient at a prompt, but they can change and two things can share one. In a script that has to keep working, save the ID a command returns and use that.

Machine-Readable Output

Most commands print a table meant for reading. Pass --json to get JSON instead, which is stable to parse and includes full IDs:

$ rex ls --json
{
  "sessions": [\
    {\
      "session_id": "session:01a10cf3-2655-7e48-9b9c-43dd6612bef5",\
      "label": "Research"\
    },\
    {\
      "session_id": "session:01a10d97-414b-79ee-9988-4d96d804ef90",\
      "label": "SL Website"\
    }\
  ]
}

The exit status says how a command ended:

Status Meaning
0 The command succeeded
1 The command failed
2 The command line was invalid
3 A target was not found or was ambiguous
4 The server could not be reached
130 The command was interrupted

Commands that wait for a program, such as rex wait and rex run --wait, exit with that program’s status instead.

PATH

When Rex opens a terminal, it puts the directory that holds the server’s rex executable at the front of PATH. It also sets REX_BIN_DIR to the same directory. Your shell’s startup files run after that. A startup file that sets PATH to a fixed list leaves rex out. One that reorders PATH can put a different copy of rex ahead of the one that matches your server.

To check, compare the two:

echo "$REX_BIN_DIR"
echo "$PATH"

If PATH doesn’t start with REX_BIN_DIR, add it back to the front at the end of your shell’s startup file. Adding it to the end of PATH instead can still pick up another copy of rex first.

# ~/.zshrc, or ~/.bashrc
if [ -n "$REX_BIN_DIR" ]; then
    export PATH="$REX_BIN_DIR:$PATH"
fi
# ~/.config/fish/config.fish
if set -q REX_BIN_DIR
    fish_add_path --path --prepend --move $REX_BIN_DIR
end

Nix

NixOS and nix-darwin set PATH to a fixed list each time a shell starts. This affects you if your PATH includes /run/current-system/sw/bin, even if you only used Nix to install your shell. Add the same check to your system configuration so it runs in every interactive bash and zsh:

environment.interactiveShellInit = ''
  if [ -n "$REX_BIN_DIR" ]; then
    export PATH="$REX_BIN_DIR:$PATH"
  fi
'';

For fish, put the fish example above in programs.fish.interactiveShellInit. With home-manager, use your shell’s init option, such as programs.zsh.initContent. Don’t add REX_BIN_DIR to home.sessionPath.

Outside Rex the variable is empty, which adds an empty entry to PATH.