tuios 0.9.0 is a big one: about 490 commits since v0.8.5. Any program can now tell tuios what it is doing, your config can live in more than one file, and yanks stay around as paste buffers. You can take a session for yourself with attach -d, your ssh agent follows you into your panes, and images show up even on a terminal with no graphics at all.
tuios-v0.9.0-hero.mp4
Before you upgrade, read Upgrading. The daemon protocol gained new messages, so restart the daemon after you install.
The full list is at tuios.dev/releases.
Watch
Six short clips, narrated by Tilly. Click one to play it, or watch them all with captions on the release page.
Program status | Split the config |
Paste buffers | One client per session |
Your ssh agent follows you | Images without graphics |
Install
brew install tuios # Homebrew (macOS, Linux)
yay -S tuios-bin # AUR (tuios-web-bin for the web server)
nix run github:Gaurav-Gosain/tuios # Nix
curl -fsSL https://raw.githubusercontent.com/Gaurav-Gosain/tuios/main/install.sh | bash
go install github.com/Gaurav-Gosain/tuios/cmd/tuios@v0.9.0
docker run -it --rm ghcr.io/gaurav-gosain/tuios:v0.9.0- A binary installed by the script or from an archive updates with
tuios update. - The ghostty build on Homebrew.
brew install gaurav-gosain/tap/tuios-ghosttyinstallstuiosbuilt with libghostty-vt, on Linux. It installs a binary with the same name as thetuiosformula, so runbrew uninstall tuiosfirst. On macOS, take thetuios-ghostty_*_Darwin_*archive from this page. - The
tuioscask is deprecated.brew install tuiosgives you the homebrew-core formula. If you installed the cask from my tap, move to the formula withbrew uninstall --cask tuios && brew install tuios.
Highlights
- Program status (OSC 7501). Any program in a pane can report that it is working, blocked, done or failed, with the Program Status Protocol. A build, a deploy script or
brewthen shows on the rail and in the Inbox like an agent, with no hook or plugin (#546). Docs: Program Status. - Split the config.
include = [...]in config.toml and aconfig.dfolder let you keep machine-only settings, such as hosts, out of your shared dotfiles. A read-only file from Nix or home-manager stays read-only, and the settings page writes its changes to a file it may change (#547, asked for in #518). Docs: Split the Config. - Paste buffers. Each yank is kept as a paste buffer, as in tmux.
Ctrl+B ]pastes the newest one andCtrl+B #lists them all.list-buffers,set-buffer,paste-bufferand the tmux shim use the same buffers (#550, asked for in #514). Docs: Paste buffers. - One client per session.
tuios attach -d NAMEdetaches every other client as you attach, astmux attach -ddoes.tuios detach-clientdetaches clients without an attach, and[daemon] single_client = truemakes every attach work like-d(#551). Docs: Detaching other clients. - Your ssh agent follows you. With
[daemon] ssh_agent = "follow", new panes use the ssh agent of the client you attached from, and they move with you when you attach from another machine. This also works through a remote host, when your ssh link forwards the agent (#552). Docs: SSH Agent. - Images without graphics. On a terminal with no sixel or kitty graphics, such as kmscon, the Linux console or a plain SSH client, tuios now draws pane images with block glyphs. kmscon gets octants, the Linux console gets half blocks, and everything else gets quadrants (#548). Docs: Images Without Graphics.
- Agents and the Inbox.
- Crush permission prompts wait in the Inbox like the others (#320). Docs: herdr Compatibility.
tuios checkpointsaves an agent's work tree at the end of each turn, and puts it back when you ask. Docs: Checkpoints.tuios shipcommits, merges, pushes and opens the pull request for a worktree. The rail shows the pull request and its checks. Docs: Ship.- The Inbox can send push notifications through ntfy, Pushover or a webhook. Try it with
tuios notify test. Docs: Push Notifications. [agents] enabled = falseturns off every agent feature, if you want a plain multiplexer (#387). Docs: Turn Off Agent Features.- The settings page has an Agents tab that installs and updates the harness integrations (#474).
- The rail. The sidebar is now shared by every client of a session, and the panes retile when you hide it (#350). You can add your own section fed by a command (#419), copy a folder's path, and turn on session numbers with
appearance.sidebar.show_numbers(#544). Docs: Session Rail. - Find a pane.
Ctrl+B /opens a navigator over every pane in every session, on this machine and on your hosts. Search names, folders, commands and the text on screen, with a live preview in the pane's own colours (#473, #505).Ctrl+B Qlabels the panes so that you can jump to one with a key (#472). Docs: Finding a pane. - herdr. tuios now hosts herdr plugins: their actions go in the palette and their panes open in tuios (#435). The herdr socket also answers the pane, agent and client methods that plugins still missed (#433). Docs: herdr Compatibility.
- tmux shim. The shim accepts command prefixes, reads the tmux 3.4 format language, and adds
wait-for,display-popup,run-shell,if-shell, pane and window moves, buffers, the environment anddetach-client. About 90 format cases are checked against a real tmux. Docs: tmux Shim. - Speed. Panes draw on one frame clock, so an animation at 120 Hz shows at 120 Hz.
max_fpsnow goes up to 240, or"auto"to follow your display (#407, #520). Copy-mode search went from 150 ms to 11 ms a key, an idle client uses less than half the CPU it did, and the daemon gives memory back after you close a lot of panes. Docs: max_fps.
More new things
Panes, layouts and workspaces
- Neovim navigation. The same keys move between nvim splits and tuios panes, with
appearance.nvim_navigation(#318). Thanks to @Tim4c. - Borderless zoom.
appearance.zoom_borderlessmakes a zoomed pane fill the whole pane area with no border (#531). - Splits over ssh.
split_ssh_horizontal,split_ssh_verticalandnew_window_sshopen the new pane on the machine the pane is ssh'd into.appearance.new_window_follow_sshmakes the normal split keys do it (#471). - Last pane.
last_pane(;in window mode) flips between the last two panes (#469). Thanks to @davidreuss. - Session keys.
switch_session_1toswitch_session_9, andrename_workspace(#464). Thanks to @davidreuss. - Empty workspaces. When the last pane on the workspace closes, tuios goes back to the workspace you showed before (#427).
[workspaces] new_window_when_empty = trueopens a pane when you switch to an empty workspace (#485). - Scrolling layout. A column can fill the whole screen (#402). Thanks to @alnav3.
Dock
- Compact dock.
appearance.dock_compactdraws the dock as one row (#461). - Rounded pills. The dock pills are rounded by default (#458).
- Mode icons.
dock_mode_icon_window,dock_mode_icon_terminalanddock_mode_icon_tilingset the mode pill icons (#529). - Labels.
appearance.dock_workspace_label_maxcaps a workspace label, and a minimized pane keeps its name while there is room (#499). Thanks to @davidreuss. - Mode keys. The keys of the current mode show as a legend in the dock.
Sessions, hosts and the CLI
- Sessions from the CLI.
tuios new --cwd DIRstarts a session in a folder, andtuios switch-session [HOST:]NAMEmoves your client to another session (#457). - Clients.
tuios list-clientslists the clients of the daemon, and aclient-session-changedevent says when one switches (#410). Thanks to @zer0ken. - Hosts.
tuios hosts syncinstalls this version on every host (#431).--startstarts the daemon on a host (#450). A Tailscale SSH check now says "sign in" and opens the page (#465, #513). - Explorers.
tuios help -i,tuios config browseandtuios keybinds browselet you search the commands, the options and the keys (#436). - Keys reload. A key you save in config.toml works at the next key press, with no restart (#454). Thanks to @davidreuss.
- Scripts. More list commands take
--json, the help is accurate, and errors say what to do (#430).tuios close-windowis new (#438). - Tapes. A tape can run any action and wait on conditions, and
tape execplays a tape to the end and reports the first failure (#437). - Launcher.
launcher.gui_commandstarts graphical desktop entries (#346). - MCP. The MCP server speaks protocol versions 2025-11-25 and 2026-07-28.
Copy mode and links
- Links. Ctrl+click opens a link, and OSC 8 links reach your outer terminal. Docs: Links.
- Home and End go to the start and end of the line in copy mode (#528).
Terminal emulation
- tuios answers XTVERSION, DA3, XTGETTCAP and DECRQSS, and supports xterm's modifyOtherKeys, the 1005 and 1015 mouse encodings and the title stack.
- Each pane gets its own key encoding, with releases, repeats and lock state as kitty sends them (#377).
- A pane that turns on focus reporting is told when it has focus (#337).
- A graphics pane is paced to its fastest client (#345).
Fixes
- A Mac config on Linux.
opt+keys now work on every platform, and one bad key no longer makes tuios drop the whole file (#559). This fixes #556. - Bare attach.
tuios attachwith no name goes to the session you used last (#495). Before, it picked one at random. This fixes #486. - Clipboard. A pane's OSC 52 copy now uses
pbcopyand the other native tools when the terminal cannot take it (#494). Thanks to @juancely. - OpenCode V2. The OpenCode integration works with OpenCode V2 (#526). Thanks to @j4ng5y.
- NetBSD. tuios builds on NetBSD again (#490). Thanks to @ci4ic4.
- Dock meters follow a live settings change (#525). Thanks to @drawde-nadroj.
- Zoom retiles when the canvas is not active (#398). Thanks to @fonnesbeck.
- A stuck client. A client wedged by a signal now exits instead of hanging (#207). Thanks to @masshirodev.
- The pointer shape goes back to normal when your terminal loses focus (#507). Thanks to @davidreuss.
- The skill parses in strict YAML readers (#481). Thanks to @chenxin-yan.
- Folders. A new window opens in the folder your shell reports with OSC 7 (#497). A session keeps its start folder across a restart (#482).
- Keys. Shift+Up and Shift+Down reach nvim, less and htop.
send-keyskeeps capital letters and uses the encoding the pane asked for (#444). - Layouts. Master-stack splits stay even across a retile (#403, #405). Shared borders hold through a resize and in the scrolling layout (#470).
- Copy mode keeps the whitespace a copy covers, and leaves out the pad of a wide character at a wrap (#527).
- Restore. One pane's screen is no longer painted into another while a session restores. Daemon replies now match their request.
- Hidden workspaces. Panes on a hidden workspace close and stream as they should (#384).
- Popups close when their command exits, in any session (#483).
- Config saves are atomic, so a reload never reads a half-written file (#409).
- The which-key menus list the keys you actually have (#530).
- The dock CPU meter works on Windows and the BSDs (#560).
- Crashes. The status line and a theme with no cursor colour no longer crash (#378).
- Windows paths. The rail reads MSYS2 and Cygwin folders (#416).
Security and robustness
- Typing over a host link. A pane on one machine can no longer answer a prompt on another machine unless that machine's link policy allows
respond(#389). - Daemon memory. The daemon checks a frame's size before it reads the frame, and all frames and requests share one read budget. A process that can reach the socket can no longer make the daemon hold a gigabyte (#557, #498).
- Paste buffers have an owner. A pane without
adminsees only its own buffers, never yours. - herdr plugins wait for you before they run, and only a pane with
adminreads the plugin log. - Dock components. Their output is bounded, and unsafe characters are removed (#404).
- ssh. A followed ssh agent socket must pass the same folder checks as OpenSSH. A split that follows ssh keeps only known connection options.
- ship and checkpoints.
shippushes the commit you allowed, not the branch tip. A restore that would overwrite ignored files is refused. Notifications refuse a redirect to another host. - MCP. Tools that change state are no longer marked read-only.
- Events.
tuios subscriberefuses an event type it does not know, instead of printing nothing (#438). - No curl. Notifications and
tuios updateuse Go's own HTTP client. tuios no longer needs curl at run time. - Fuzzing. Every fuzz target now runs in the nightly job (#503).
Upgrading
Restart the daemon
The protocol gained new messages for detach, session use, the shared sidebar, image glyphs, the ssh agent and request ids. Restart the daemon after you upgrade:
tuios kill-serverThis closes every pane in every session, so save your work first. For your remote hosts, tuios hosts sync --restart installs this version and restarts each daemon. An older daemon ignores attach -d, and tuios attach -d warns you when that happens.
Config
-
opt+isalt+everywhere. A key such asopt+1now reads asalt+1on Linux too, so one config.toml works on a Mac and on Linux. On macOS,opt+keys work as before. -
One bad key drops only that key. tuios keeps the rest of the file and shows "N config problems, see the log viewer". Before, one bad key put every setting back to its default.
-
config.toml is sparse. tuios now writes only the keys you changed, so that included files can apply. An older config.toml that lists every key holds every default too, and those keys win over your included files. To clean it, run:
tuios config prune --dry-run # see what it removes tuios config pruneIt keeps your comments and
[startup], and asks before it removes a key that another file sets.
Images
- chafa, timg and yazi now send sixel on hosts without graphics. tuios tells panes that they can draw sixel and draws the image as glyphs. These tools then send sixel instead of their own text art. To go back to the box, set
appearance.image_symbols = "off".
Changed defaults
- Agent checkpoints are on. At the end of each turn that changes a file, tuios saves the agent's work tree under
refs/tuios/checkpoints/in that repository. To turn it off, set[agents.checkpoints] enabled = false. - The dock pills are rounded. Set
appearance.dock_pill_caps = falsefor the flat dock. - An empty workspace goes back. When its last pane closes, tuios shows the workspace you used before. Set
[workspaces] return_when_empty = falseto stay. - A bare
tuios attachgoes to the session you used last. tuios newstarts the session in the folder you run it from. Before, it used the daemon's folder.- New default keys:
Ctrl+B ]pastes a buffer,Ctrl+B #lists the buffers,Ctrl+B /opens the pane navigator andCtrl+B Qlabels the panes.tuios keybinds doctornames any clash with your own keys. - Shift+Up and Shift+Down scroll only a pane on the main screen with no mouse mode. A full-screen program gets the keys.
- Mode keys show as a legend in the dock, not as a message.
For scripts
- A pane's
TERMis now one that this machine has a terminfo entry for. DA1 reports only what the emulator does:62;22, or62;4;22with sixel. - Tapes stop at the first failure.
tape playexits non-zero after a failed tape. tuios subscribe --typesrefuses an unknown event type.- Typing over a host link into a pane that waits on a prompt needs
respondin that host's[hosts]link policy.
Contributors
Thank you to everyone who sent a pull request for this release:
- @Tim4c: seamless nvim pane navigation (#318)
- @davidreuss:
last_pane, the session keys andrename_workspace, keybinding reload, the dock label cap, the pointer shape fix and the rail numbers (#469, #464, #454, #499, #507, #544) - @JakeChop: the custom rail section (#399)
- @zer0ken:
list-clientsand the client event (#391) - @alnav3: the full-screen scrolling column (#396)
- @fonnesbeck: the zoom retile fix (#398)
- @masshirodev: the signal-wedged client fix (#207)
- @juancely: the OSC 52 clipboard fallback (#492)
- @j4ng5y: OpenCode V2 support (#517)
- @drawde-nadroj: the dock meter fix (#522)
- @ci4ic4: the NetBSD build (#490)
- @chenxin-yan: the skill frontmatter fix (#476)
And thanks to everyone who asked for things and reported bugs: @adamcstephens for the config includes (#518) and the ssh agent and single client ideas (#549), @iTerminate for paste buffers (#514), @Smithx10 for the navigator, ssh splits, the compact dock and the xpanes return (#467, #468, #459, #273), @chenxin-yan for the attach and empty workspace reports (#486, #477), and @stonevil for the config report (#556).
Full Changelog: v0.8.5...v0.9.0