Rex
tuios integration install rex adds the tuios command palette to Rex, with your own actions, and TUIOS tells Rex when an agent waits and what each pane is doing.
Rex is a terminal multiplexer app. TUIOS adds actions to Rex's command palette that work on the TUIOS session shown in the focused Rex pane. It also tells Rex when an agent needs you, and what each pane is doing.
Install
tuios integration install rexThis does four things:
- It writes
tuios.luanext to Rex'sinit.lua. Rex findsinit.luaatREX_CONFIG, else$XDG_CONFIG_HOME/rex/init.lua, else~/.config/rex/init.lua. - It adds one line to
init.lua:require("tuios").setup{} -- added by tuios integration. Nothing else in the file changes. Wheninit.luaalready requires tuios on a line of your own, that line is kept and no line is added. - It runs
rex config check. When Rex refuses the config, both files are put back as they were and the command prints Rex's message. - It runs
rex config reload, then thetuios_checkaction inside Rex, and prints which tuios the actions run and whether Start an Agent finds its agent.
The first time it rewrites init.lua, the file as it was is kept as init.lua.tuios.bak. A tuios.lua with changes of your own is left alone. --force replaces it and keeps yours as tuios.lua.tuios.bak. An older tuios.lua that TUIOS wrote is replaced.
tuios integration status rex # the files, whether Rex loaded them, what tuios_check says
tuios integration uninstall rex # removes the marked line and tuios.lua, then reloadsThe actions
The actions are TUIOS's own. Each row of the TUIOS command palette that runs as a key would is one action, read from tuios actions --json each time Rex loads its config. A new TUIOS action shows in Rex's palette with no change to tuios.lua. Each is named tuios_ and the TUIOS action name, and titled tuios: and the palette row, such as tuios_prefix_inbox, "tuios: Agents: What Needs You". rex actions | grep tuios_ lists them all. Among them:
| Action | Palette title | What it does |
|---|---|---|
tuios_goto_picker | tuios: Go To: An Agent, Session, Workspace or Pane | Opens the go-to picker, with each agent's state |
tuios_prefix_inbox | tuios: Agents: What Needs You | Opens the agents view, as Ctrl+B i does |
tuios_prefix_mail | tuios: Agents: Mail for You | Opens the agents view on your mail |
tuios_prefix_next_attention | tuios: Agents: Go to the Oldest Waiting | Moves the focus to the oldest item that needs you |
tuios_new_window, tuios_layout_bsp, tuios_prefix_review, tuios_prefix_selection, tuios_screenshot and more | The window, layout, review, copy mode and screenshot rows of the palette | |
tuios_user_NAME | tuios: your label | Your own actions, user:NAME |
Your own actions
Your [[actions]] and [[keybindings.command]] entries are in the palette too (see Your actions). They come from the config.toml that Rex's server finds: $XDG_CONFIG_HOME/tuios, else ~/.config/tuios.
- A dash in the name is an underscore in Rex, since a Rex action name has only lowercase letters, digits and underscores.
user:open-in-editoristuios_user_open_in_editor. - Two names that come out the same, such as
a-banda_b, keep the first.tuios_checknames the other. - The palette title is your
labelas you wrote it. - An action offered only on a card, a file or another target that is not a pane is left out, since Rex runs it on the focused pane.
- When TUIOS cannot read
config.toml, Rex still gets the built-in actions, andtuios_checksays why.
Run rex config reload after you add an action.
Start an agent, and the check
Two more actions are written in tuios.lua:
| Action | Palette title | What it does |
|---|---|---|
tuios_start_agent | tuios: Start an Agent | With no field given, opens the New agent sheet. With fields, starts the agent in a new TUIOS pane and focuses it |
tuios_check | tuios: Check the Rex Integration | Says which tuios the actions run, its version, the focused pane's session, whether the default agent is found, and whether Rex has the actions this tuios lists |
Start an Agent takes harness, name, prompt, folder and machine (a machine of the [hosts] table). The harnesses TUIOS knows are the choices rex actions --json shows for harness. Rex does not hold a value to that list, so any program start-agent can run works too.
rex do tuios_start_agent harness=codex name=review prompt='Review the diff.' folder=~/src/appThe go-to picker and the New agent sheet are TUIOS's own, drawn in the focused pane. A Lua action in Rex has no picker or form of its own to open, and a list made when Rex loads its config is out of date by the time it is used, while TUIOS's own are always current.
When TUIOS is updated
tuios.lua reads the list at each config load, so rex config reload picks up the actions of a new TUIOS. tuios integration install rex reloads too. tuios integration status rex says when the list Rex loaded is not the one the TUIOS on disk gives, and to reload.
When TUIOS cannot give the list (none is found, or one older than this tuios.lua), Rex still loads the config, with the go-to, agents view, mail, oldest waiting, Start an Agent and check actions. tuios_check says why.
Keys
Keys are off until you name them. keys = "suggested" binds this set:
| Key | Action |
|---|---|
| Ctrl+Cmd+A | tuios_prefix_inbox: the agents view on what needs you |
| Ctrl+Cmd+J | tuios_prefix_next_attention: jump to the agent that has waited longest |
| Ctrl+Cmd+G | tuios_goto_picker: go to an agent, session, workspace or pane |
| Ctrl+Cmd+M | tuios_prefix_mail: your mail |
| Ctrl+Cmd+N | tuios_start_agent: the New agent sheet |
Each holds cmd, which a Mac never sends to a program in a terminal, so no key of TUIOS's (such as Ctrl+B) or of your shell's is taken. None is a default key of Rex for Mac or a macOS ctrl+cmd shortcut: ctrl+cmd+q locks the screen, ctrl+cmd+f is full screen, ctrl+cmd+d looks a word up, and Rex has ctrl+cmd+i. A key you bound in Rex's settings, or with rex.bind above the require line, is replaced by the newest binding, so put your own rex.bind lines after it.
require("tuios").setup{
bin = "tuios", -- the tuios program; see "Finding tuios and the agents"
harness = "claude", -- the agent tuios_start_agent starts when no harness is given
keys = "suggested",
}
-- The set with changes: your keys on top, false to leave one unbound.
require("tuios").setup{
keys = { suggested = true, tuios_prefix_mail = false, tuios_new_window = "ctrl+cmd+w" },
}
-- Only keys of your own.
require("tuios").setup{
keys = { tuios_prefix_inbox = "cmd+shift+a", tuios_prefix_next_attention = "cmd+shift+j" },
}The names of the earlier tuios.lua, tuios_agents, tuios_mail and tuios_next_waiting, still bind the same actions. A key for an action Rex does not have is left unbound, and tuios_check names it, so a key for an action a later TUIOS drops never stops Rex loading the rest of init.lua.
Agents that wait
When an agent needs you (a question, an approval, a login), the TUIOS client in the Rex pane tells Rex in two ways, with nothing to set up:
- A notification. TUIOS writes OSC 9 with the pane's name and what the agent asked, such as
review needs you · approve Bash: make. Rex raises it as a desktop notification when Settings, Notifications, System Notifications, Terminal notifications is on.[notifications.agent]inconfig.tomlsays which states alert. - A status record. TUIOS reports its agents' state with OSC 7501, the Program Status Protocol. Rex shows it on the tab and in the session picker. With Settings, Notifications, Program Activity, Show system notifications on, Rex raises a macOS notification while it is in the background. Rex's docs say a click on that one opens the program's tab. See Per-pane status for one record per agent.
None for what you are looking at. TUIOS asks its terminal for focus events, and Rex sends them when its focus moves between panes. While Rex shows the TUIOS pane, TUIOS writes no notification for the TUIOS pane that has the focus (suppress_focused, on by default). Another TUIOS pane still notifies, and so does the focused one while Rex shows another pane or tab.
Jump to it. Rex has no notification with a button, and a Lua action cannot raise one. Once Rex shows the TUIOS pane, tuios_prefix_next_attention ("tuios: Agents: Go to the Oldest Waiting") moves the focus to the agent that has waited longest, and tuios_prefix_inbox opens the agents view on what needs you. In the suggested keys they are Ctrl+Cmd+J and Ctrl+Cmd+A.
Two notifications for one question. With Rex in the background and both Rex settings above on, one question can give two macOS notifications, one from each. Keep one: turn off Rex's Terminal notifications, or set notify = false under [notifications.agent] in TUIOS. The status record still reaches Rex.
What was checked
In a real Rex server, another pane's question, and the focused pane's question while Rex showed another pane, each gave one desktop notification. The focused pane's question while Rex showed TUIOS gave none, before and after Rex's focus events. What the Mac app draws for them was not checked, since that server has no app attached.
Per-pane status
By default TUIOS gives Rex one status record (OSC 7501) for each TUIOS session: the most urgent state of its agents, and a message that counts them, such as 1 needs input, 2 working. Rex shows one status for each Rex pane, so a TUIOS session with many agents shows as one.
For one record per agent, set this in config.toml:
[agents]
host_program_status = "panes"Each TUIOS pane with an agent then has a record of its own, with the pane's name as the title and what the agent asked or is doing as the message, under the id SESSION/PANE. "off" sends none. A client reads the value when it starts and when config.toml changes. tuios integration status rex says which one is set.
In a real Rex server the Rex pane's program_status held the one record demo by default. With "panes" it held demo/PANE for each pane with an agent, in the blocked state with the pane's title and the agent's question as the message. How the Mac app's sidebar and Activity view draw several records from one Rex pane, and what the iOS app shows, was not checked.
Finding tuios and the agents
The Rex server is started by the app, so its PATH has none of the folders a login shell adds, such as ~/.local/bin.
tuios.lualooks for tuios onPATH, then in~/.local/bin,/opt/homebrew/bin,/usr/local/bin,$GOBIN,$GOPATH/bin,~/go/binand the Nix profiles. When none has it, the action says where it looked. Give the full path then:setup{ bin = "/full/path/tuios" }.tuios start-agentlooks for the agent on thePATHits caller sent, then on the daemon'sPATH, the one a new pane gets, and runs the agent with thatPATH. So an agent you can start in a TUIOS pane starts from Rex too.
How an action finds the session
An action asks Rex for the focused pane's foreground process. When that is a TUIOS client, tuios list-clients --json has its pid with the session it shows. A pane that runs a shell, or ssh to another machine, shows no TUIOS client on this machine, and the action says so.
The TUIOS actions run tuios run-command -s SESSION Action NAME, which the client showing the session runs as its key would. Start an Agent runs tuios start-agent --no-wait, which answers once the agent has started, well inside the 30 seconds Rex gives an action, so a failure shows as TUIOS's own message. The prompt is typed once the agent is ready.
Limits
Only a TUIOS client on the same machine as the Rex server is found. The TUIOS actions need the TUIOS client in the focused pane, since that client runs them. Rex's palette lists the agent actions before any agent has run, while TUIOS's own palette waits for one. install talks to the local Rex server, or the one REX_SERVER names.
Neovim
Two community plugins connect Neovim to tuios. One moves between splits and panes. One gives Neovim the colours of your look.
Images Without Graphics
How TUIOS shows sixel and kitty graphics pictures as block characters on kmscon, the Linux console and other terminals without graphics.
tuios lives only at tuios.dev and github.com/Gaurav-Gosain/tuios. tuios has no X or Twitter account. An account that offers a tuios token or presale is not this project.