Multi-session coding-agent orchestrator
TUI Agentic IDE
Run Claude Code, Codex, Antigravity, opencode, aider, GitHub Copilot CLI, Vibe, pi, Oh My Pi — or any CLI you define — side by side in persistent tmux panes that survive crashes and restarts.
And every pane you see is a Lua file in a directory you own — the session list included. Turn one off, reorder them, or write your own.
One command
Install it, then run
thurbox
— that is the whole setup. Sessions, agents, themes and the interface itself are
seeded on first launch.
Linux & macOS, and the
recommended
route. Auto-detects your platform, verifies checksums, and installs both
thurbox
and
thurbox-cli
to
~/.local/bin
.
curl -fsSL https://raw.githubusercontent.com/Thurbeen/thurbox/main/scripts/install.sh | shThen run it:
thurbox
Native Windows (PowerShell 5.1+), and the
recommended route
on Windows — unlike winget and Chocolatey it always carries the newest release.
Verifies checksums and installs to
%LOCALAPPDATA%\Programs\thurbox
(added to your user
PATH
). Needs
psmux
as the multiplexer (installed separately).
irm https://raw.githubusercontent.com/Thurbeen/thurbox/main/scripts/install.ps1 | iexThen run it:
thurbox
Windows x86_64 via
winget
(bundled with Windows 10/11). Installs the prebuilt
thurbox.exe
+
thurbox-cli.exe
as portable commands on your
PATH
. Needs
psmux
as the multiplexer (installed separately).
Heads-up: winget-pkgs is manually moderated, so thurbox submits a new version there at most once every 30 days — this channel trails the newest build. For the latest release right away, use the PowerShell installer.
winget install Thurbeen.thurbox
Windows x86_64 via the
Chocolatey community repository
. Installs the prebuilt
thurbox.exe
+
thurbox-cli.exe
and shims them onto your
PATH
. Needs
psmux
as the multiplexer (installed separately).
Heads-up: the Chocolatey community repo is moderated and rate-limited, so thurbox pushes a new version there at most once every 30 days — this channel trails the newest build. For the latest release right away, use the PowerShell installer.
choco install thurbox
macOS (Apple Silicon) & Linux x86_64. Prebuilt binaries from the
thurbox tap
; pulls in
tmux
and
git
automatically.
brew install thurbeen/thurbox/thurbox
thurbox-bin
(prebuilt binary) or
thurbox
(builds from source) — use
paru
,
yay
, or your preferred AUR helper.
paru -S thurbox-bin # prebuilt (fastest)
paru -S thurbox # build from source
Any platform with Rust 1.75+. Builds both the
thurbox
TUI and the
thurbox-cli
headless binary into
target/release/
.
git clone https://github.com/Thurbeen/thurbox.git
cd thurbox
cargo build --releaseEvery pane is a plugin
The interface is a directory you can edit
The session list, the agent terminal, the search strip — each one is a Lua file
under ui/plugins/. Move it, turn it off, replace it with your own, and the
arrangement closes up around what is left. No recompile, no restart.
ui/layout.lua — arrangement
ui/plugins/ — click to turn off
▸ Autoplaying — click anything to take over.
That last one is not shipped. thurbox-cli plugin new git-status writes a file
that already loads, and it is a pane the moment you save it. A plugin gets no filesystem
and no network — it draws, and the kernel does the rest. Adding or removing a pane is
two edits, as it is above: the plugin, and the slot in
ui/layout.lua that says where it goes.
“Stacked right” is a demo you can run.
Those two panes are real, distributed panes — a tasks list, and CPU and memory read
from
top
— with an arrangement that puts them in a column beside the agent. Install them,
copy the arrangement, and press
F10
:
thurbox-cli plugin install tasks
thurbox-cli plugin install top
cp examples/lua/layout.lua ~/.config/thurbox/ui/layout.lua
Each install records itself in
plugins.toml
beside your panes and prints the
layout.lua
line the new pane needs — because a pane whose slot nothing places loads perfectly
and draws nothing, and
thurbox-cli plugin check
is what fails on it. The arrangement is copied rather than installed on purpose: the
manager never writes that file.
The tasks pane needs no permission — it reads the same records
thurbox-cli task
does and writes back as commands. The
top
one asks to
run a program
, so it draws nothing until you trust the file (settings → Interface →
t
). It then reads the machine
the selected session runs on
, which means picking a session over SSH shows you that host's load — without the
plugin knowing what SSH is.
Or just ask the agent. You do not have to learn Lua to change any of this. thurbox runs coding agents, and the interface is a directory of plain text files those agents can read — so point a session at it and say what you want:
thurbox-cli session create --name ui --repo-path ~/.config/thurbox/ui- Install the info panel plugin.
-
Add a new pane on the left with CPU and RAM usage. There is a
topexample plugin — install it and give it a slot in the layout. - Move the search strip to the bottom, and make the session column 30% wide.
It works because the directory ships an
AGENTS.md
that any coding CLI loads as context without being asked — so
“install a plugin” is read as
thurbox-cli plugin install
rather than an npm request, and the agent knows
thurbox-cli plugin check
is how it verifies its own work. Press
F10
and the change is on your screen.
The worked example →
Not a config format
This is the whole plugin
A plugin is a table. It names a slot to occupy, declares the chords it wants, and returns
what it drew — and there are only ever
four node kinds
(text, box, input, surface). Lists,
panels and tables are not kinds; they compose from those, in Lua, in
ui/lib/.
ui/plugins/90_git.lualocal theme = require("lib.theme")
local widgets = require("lib.widgets")
return {
name = "git",
slot = "center",
order = 90,
focusable = true,
-- Declaring it is not being granted it: until you
-- trust this file, the `run` global is *absent*.
capabilities = { "run" },
keys = {
{ key = "f8", action = "git.open",
desc = "repo at a glance", scope = "global" },
},
render = function(ctx)
-- `run` is nil until the file is trusted, so this
-- checks rather than assuming.
if not run then
return { type = "text", text = theme.dim(" not trusted") }
end
local id = store.selected
if not id then
return { type = "text", text = theme.dim(" no session") }
end
-- Asked every frame, on purpose. A worker answers;
-- a fresh answer is a map lookup, not a process.
run("status", "git status --porcelain",
{ session = id, ttl = 2 })
local got = thurbox.runs["status"]
local rows = {}
if got and got.ok then
for line in got.stdout:gmatch("[^\n]+") do
rows[#rows + 1] = { spans = { {
text = " " .. widgets.truncate(line, ctx.width - 4),
style = { fg = line:find("^%s*M") and theme.warn
or theme.secondary },
} } }
end
end
return {
type = "box",
frame = widgets.panel("git", ctx.focused),
children = {
widgets.list({ rows = rows, height = ctx.height - 2 }),
},
}
end,
}
→ and that is a pane
-
It never blocks.
ctx.runasks; a worker answers next frame. Calling it every frame is the intended pattern, because a fresh answer is a map lookup rather than a process. -
It gets no more than it asked for.
No filesystem, no network, no
osorio— those are absent from the sandbox, not blocked in it. Running a program is a capability, and it stays inert until you trust the file.
Features
A fixed engine under an interface that is entirely yours
Band 1 — compiled, fixed
The engine
Processes, git, hosts, schedules, the database. This half is Rust and it is not yours to edit — which is the point: it is what a plugin is allowed to be careless in front of.
Persistent Sessions
Run multiple coding-agent CLIs side-by-side, each in its own tmux pane. Sessions persist across crashes, restarts, and multiple concurrent Thurbox instances.
Git Worktrees & Sync
Spawn sessions in isolated git worktrees for branch-level isolation. One-key sync (
Ctrl+S
) rebases all worktrees from origin/main, with automatic conflict resolution and
worktree cleanup on session close.
Any Coding Agent
A session runs one agent of your choice — Claude Code, Codex, Antigravity, opencode, aider, GitHub Copilot CLI, Vibe, pi, Oh My Pi, or any CLI you describe. Each agent runs with its own default config. Mix different agents across the sidebar.
Agent Definitions
Agents are declared as data in
~/.config/thurbox/agents.toml
, seeded with built-ins on first run. Add or tweak an agent — command and
argument templates — with no recompile.
Automations
Named, scheduled agent runs — one-shot or recurring cron. On schedule they send a prompt to a session, spawn a fresh one, or run a plain shell command. A detached tmux keeper fires them whether or not thurbox is open .
Tasks & issue sync
A todo list whose items
connect to a coding agent
— send one into a running session or spawn a fresh one seeded with it. Syncs
Records carry a
source
and an external id, so a sync script of your own can import from a tracker
without thurbox knowing which one.
Remote & WSL Hosts
Run an agent on another machine while the interface stays local — over SSH, or in a WSL distro that is discovered with no config . The agent, its tmux window and its worktrees all live on that host.
Extensions
Opt-in,
agent-agnostic
add-ons that compose Thurbox through
thurbox-cli
— never the binary. Install one from a declarative manifest in a single
command, and Thurbox keeps its session and automation
self-healed
. Two ship built in;
fleet
is the worked example of one you install yourself.
Headless CLI
The
thurbox-cli
binary scripts everything from the terminal: create and drive sessions, schedule
commands, pass messages between agents — all against the same SQLite database
the interface reads.
Band 2 — Lua, yours
The interface
Everything you look at. Not a theme layer over fixed panes — the panes themselves, the arrangement that places them, and the keys that reach them are files in a directory you own.
Every pane is a file
The session list included. Move one, turn it off, delete it, or write your own — and the arrangement closes up around what is left rather than leaving a hole. No recompile, no restart.
The arrangement is a file
No breakpoint is compiled into the binary.
ui/layout.lua
is a function of the available size, so the thresholds, the split, and the order
of the bands are yours to change.
A pane can run a program
git status
,
docker compose ps
,
npm outdated
— in the session's own directory, on the session's own host. Bounded by the
kernel and granted only to a plugin
you have trusted
.
Keys are declared, not fixed
A plugin declares the chords it wants and they appear in help. Rebind any of them live from the help screen; a pane that is turned off declares nothing , so its chord goes quiet instead of lingering.
Search that reads screens
Ctrl+/
finds a session by its name, branch, repo —
or by the error on its screen
. Matches highlight in the pane itself, and nothing pays for it while the strip is
closed.
Thirty-six palettes
Twenty-eight dark and eight light, switched live with
Ctrl+Y
and persisted. Add your own in
themes.toml
from a base plus the colours you want to override.
How It Works
Three steps from launch to coding
Launch
Start Thurbox. The session sidebar and terminal panel appear.
thurboxCreate a Session
Press
Ctrl+N
to pick repos, name the session, then choose an agent.
Ctrl+N New session # Pick repo: ~/projects/my-app # Name: my-app Agent: claude
Start Coding
Spin up sessions (optionally on a fresh git worktree) and start working with the agent. Navigate, sync, and fork with Vim-inspired keys.
Ctrl+N New session Ctrl+J Next session Ctrl+K Previous Ctrl+/ Search sessions and their screens Ctrl+S Sync worktrees with origin/main Ctrl+R Restart active session Ctrl+F Fork active session Ctrl+O Open repos in editor Ctrl+, Settings, incl. the Interface tab
You are already in a coding agent
Just ask for it
thurbox-cli
is installed beside
thurbox
and the interface is a directory of text files — so the two things you would
otherwise script by hand are a sentence from inside any session.
Orchestrate sessions
The headless CLI creates, prompts, forks and tears down sessions, so an agent can spin up a whole fleet for you. Everything it does appears in your running TUI within a tick — both binaries share one SQLite database.
-
Using
thurbox-cli, start refactor sessions for this repo — one per crate, each on its own worktree branch offmain, and send each one a prompt to refactor its crate. - Spawn a reviewer session on this repo with no worktree, and send it standing instructions to review every file I change.
-
Create a nightly automation that sends “triage new issues” to the
triagesession on weekdays at 09:00.
Reshape the interface
Every pane is a Lua file, so changing the UI is also just a request. It works from
any
session, in whichever CLI you run, because thurbox ships a
thurbox-ui
skill that loads when the request is about the interface. Press
F10
and the change is on your screen.
- Add my project logs within a dedicated pane on the right in the thurbox UI.
-
Add a pane on the left with CPU and RAM usage. There is a
topexample plugin — install it and give it a slot in the layout. - Move the search strip to the bottom and make the session column 30% wide.
- Install the info panel plugin.
Feature walkthrough
See the TUI in action — recorded from the real app
Ctrl+, → Interface
The interface, editing itself
The Interface tab lists every file that makes up what you are looking at —
bundled ones saying nothing, the two panes from
examples/panes/
marked
yours
, and
layout.lua
marked
edited
because the demo replaced the shipped one. Here
85_top.lua
— a pane thurbox never shipped — is switched off with
space
: the file stays on disk, intact, and its row is not reserved, so the tasks pane
takes the whole column. The same machinery, for a file you wrote.
Ctrl+/
Search that reads screens
Find a session by its name, agent, branch or repo — or by the error printed on
its screen. Matches highlight
in the session list itself
rather than being reprinted in the strip, and
Esc
puts back exactly what you were looking at.
Ctrl+N
Session creation
Spin up a session in a few keystrokes: pick one or more repos, name it, and choose an agent — optionally on a fresh git worktree for branch isolation.
Learn more →Ctrl+Y
Themes
Thirty-six built-in palettes — twenty-eight dark, eight light — switch
live with a keystroke and persist across restarts. Bring your own in
themes.toml
: pick a base, override the colours you care about.
Prerequisites
What you need before running Thurbox — plus extra install options
Custom Directory
export INSTALL_DIR=/usr/local/bin
Pin a version
export VERSION=v2.5.4
$env:THURBOX_VERSION = 'v2.5.4'
Full Guide
Prerequisites
- tmux >= 3.2 — session backend
- A coding-agent CLI — e.g. claude , codex, antigravity, opencode, aider, copilot, vibe, pi, or omp
- git — required for worktree features
- Rust 1.75+ — only for building from source (optional)