Features

Sessions #

Heads up: The session list display is not yet perfect and will keep improving — what it can show is heavily dependent on the signals each agent CLI exposes.

Creating a session with Ctrl+N : pick a repo, name it, choose an agent.

Run multiple coding-agent CLIs side-by-side, each in its own tmux pane. A session runs one agent (Claude Code, Codex, Gemini CLI, opencode, aider, Vibe, or your own), each with its own default config. Sessions persist across crashes, restarts, and even multiple concurrent Thurbox instances — tmux keeps them alive in the background.

  • Create a session with Ctrl+N : repo picker → session name → agent picker. The agent picker is skipped when only one agent is defined.
  • Restart a session with Ctrl+R to preserve conversation history when the agent supports resume (e.g. Claude's --resume ).
  • Each session displays elapsed time ("Waiting 45s", "Idle 2m")
  • Open URLs in terminal output with Ctrl+Click
  • Select text with mouse drag, copy with Ctrl+C , paste with Ctrl+V . With no selection, Ctrl+C sends SIGINT to the active session.
  • Toggle a shell pane alongside the agent session with Ctrl+T
  • Recover sessions externally at any time with tmux -L thurbox attach

Agent Definitions #

The set of available agents is data, not code. On first run Thurbox seeds ~/.config/thurbox/agents.toml with built-ins (claude, codex, gemini, opencode, aider, vibe). Edit the file to tweak an agent or add a new one — no recompile required.

  • Each [[agents]] entry has a command , args (always passed — bake in flags like a model here if you want), and argument-template groups ( resume_args , fork_args , new_session_args ).
  • A group is appended only when its driving value is present, with {id} substituted. Selection precedence is fork > resume > new-session id.
  • A session is fully described by its repos and agent. There is no per-session model selection, permissions, prompt, tool, or skill configuration — those belong to the agent CLI itself, which runs with its own default config.

Automations #

Note: Automations are stable and good enough for daily use today, but the feature may still evolve.

Named, scheduled agent runs. An automation fires on a schedule and either sends a prompt to a running session or spawns a fresh session (optionally on a new git worktree) and prompts it. Press Ctrl+P for the full list, or use the always-present Automations pane beneath the session list.

  • Schedules are one-shot (a relative delay) or recurring cron, with friendly hourly / daily / weekdays / weekly presets and an optional timezone. The editor needs no cron knowledge: the trigger is a selector, the time is set with steppers, and a live preview shows the next fire.
  • The Automations pane joins the Ctrl+H / Ctrl+L focus cycle; once focused, Ctrl+N creates and j / k / Space / r / e / d select / toggle / run / edit / delete.
  • Automations fire even when the TUI is closed — a detached tmux heartbeat keeper runs them every minute (and keeps the tmux server alive), with opt-in systemd/launchd units for reboot-proof firing. Concurrent firers are de-duplicated by an atomic claim, so nothing double-fires.
  • Everything is persisted in SQLite ( automations + automation_runs history) and scriptable headlessly via thurbox-cli automation create/list/edit/run/runs/tick .

Tasks #

Heads up: Tasks are a new feature — expect the UX and UI to keep evolving in upcoming releases.

Building a todo list and wiring items to an agent with Ctrl+W .

A built-in todo list whose items can be connected to a coding agent with the same Send/Spawn model as automations: Send pastes the task title into an existing session, Spawn creates a fresh session (optionally on a new worktree) seeded with the title, and an unconnected task is a plain local todo. Triggering a task runs its action and advances it to in progress .

  • Tasks render in a toggleable right-side column ( Ctrl+W / F5 ) that behaves like the file viewer and joins the Ctrl+H / Ctrl+L focus cycle. Once focused, n creates, e / Enter opens an in-pane editor (no popup), Space cycles status (☐ todo · ◐ in progress · ☑ done), r runs the action, and d deletes.
  • Persisted in SQLite and scriptable headlessly via thurbox-cli task (alias todo ): create/list/show/edit/remove/run . External issue-tracker sync (Jira, GitHub Issues) is scaffolded for a later release.

Git Worktrees #

Optionally spawn sessions inside git worktrees for branch isolation.

  • When creating a session ( Ctrl+N ), choose "Worktree" mode to select a base branch and name a new branch
  • Thurbox creates the worktree and launches the agent inside it
  • Press Ctrl+S to sync all worktree sessions with origin/main
  • On rebase conflicts, Thurbox automatically sends a resolution prompt to the agent
  • Closing a session automatically removes the worktree
  • Worktree sessions show the branch name in the terminal title and session list

Worktree storage

Worktrees are created at <repo>/.git/thurbox-worktrees/<sanitized-branch> , where / in branch names is replaced by - .

Remote SSH Sessions #

Run an agent on a remote machine over SSH while the TUI stays local. The agent process, its tmux window, and any git worktrees all live on the remote host.

  • Declare hosts in ~/.config/thurbox/hosts.toml (seeded commented-out, so a fresh install has none); each entry registers a selectable backend named ssh:<name>
  • The new-session flow ( Ctrl+N ) shows a host picker first; remote sessions are marked with a glyph in the session list
  • Thurbox shells out to your system ssh , so authentication, keys, and connection multiplexing come from ~/.ssh/config — thurbox never handles credentials
  • Remote sessions get the same persistence, multi-instance sharing, and restore-on-startup as local ones
  • The remote host needs tmux ≥ 3.2 and git
# ~/.config/thurbox/hosts.toml
[[hosts]]
name = "devbox"            # backend "ssh:devbox"; what --host expects
destination = "me@devbox"  # ssh target or a ~/.ssh/config alias
ssh_opts = ["-o", "ControlMaster=auto", "-o", "ControlPersist=10m"]
# socket / session  — optional remote tmux -L / session-name overrides
# worktrees_dir      — optional absolute remote worktrees dir

Spawn remotely from the CLI with thurbox-cli session create --host devbox … .

Worktree Sync #

Ctrl+S synchronizes all worktree sessions with their upstream default branch.

  • Sessions are grouped by repository to avoid git lock contention. Different repos sync in parallel.
  • Per-worktree: stash uncommitted changes, fetch, rebase origin/main , stash pop.
  • Stale .git/index.lock files from crashed git processes are automatically cleaned up before syncing.
  • Runs on background threads — the TUI remains fully responsive.
  • Results shown per-session: synced, conflict (sent to Claude for resolution), or error.

Session Forking #

Press Ctrl+F to fork the active session. This creates a new session that resumes from the same conversation history, allowing you to explore alternative approaches without losing the original session's context.

One strip, Ctrl+A , searching every scope at once.

Press Ctrl+A to open a non-modal search strip that searches every scope at once — sessions, tasks, automations, and the active session's file tree. It is the one search: the old per-pane / filters were folded into it.

  • Sessions match on name, agent, and worktree branch and on live terminal-buffer content; tasks match on title, automations on name, and files on path.
  • Matches highlight live in the panels themselves — matching rows are accented, the rest dimmed — with per-scope match counts and a grouped result list.
  • / move the selection (previewing the owning panel), Enter jumps to the result and focuses its pane, and Esc restores exactly what you had before searching.

Responsive UI #

Three layout tiers adapt to your terminal width:

Width Layout
< 80 cols Terminal only
>= 80 cols Session sidebar + terminal
>= 120 cols Sidebar + terminal + info panel
  • Scrollback with Shift+arrows / PageUp / PageDown / mouse wheel
  • Non-modal error messages in the status bar
  • Vim-inspired keybindings throughout
  • Tri-state focus system (Focused, Active, Inactive) with visual border feedback
The info panel ( Ctrl+B ) — session details plus live CPU/RAM and agent metrics.
The file viewer ( Ctrl+E ) — browse the worktree tree with fuzzy search.

Themes #

Eight built-in palettes (four dark, four light) switch live with Ctrl+Y and persist across restarts.

Cycling palettes with the theme picker ( Ctrl+Y ).

Session Persistence #

Sessions run inside a dedicated tmux server ( tmux -L thurbox ) and survive crashes, restarts, and multiple concurrent instances.

How it works

  • Sessions spawn as tmux windows. The tmux pane keeps running regardless of Thurbox's lifecycle.
  • On shutdown ( Ctrl+Q ), session metadata is saved to SQLite. Thurbox detaches without killing sessions.
  • On restart, Thurbox discovers existing sessions from tmux, matches them to persisted metadata, and adopts them with terminal content intact.
  • External recovery is always possible via tmux -L thurbox attach .

Close vs Quit

Action Behavior
Ctrl+Q (Quit) Detaches all sessions, saves metadata. Sessions resume on next launch.
Ctrl+D (Close) Permanently kills the tmux pane. Worktree (if any) is removed immediately.

Headless CLI #

The thurbox-cli binary drives the same sessions, automations, and editor settings without the TUI — ideal for scripting. It shares the TUI's SQLite database and tmux -L thurbox server, so changes made by either show up live in the other. Every command prints JSON; pass the global --pretty flag for indented output.

$ thurbox-cli session list
$ thurbox-cli session create --name reviewer --repo-path /path/to/repo --agent codex
$ thurbox-cli session send <uuid> "run the test suite"
$ thurbox-cli session capture <uuid> --lines 500
  • sessionlist , get , create (synchronous — the tmux window is live on return; supports --worktree-branch / --base-branch ), send , capture , restart , delete , restore .
  • automation (alias auto ) — create / list / show / edit / remove / run / runs , plus tick (the headless entry point that fires all due automations — what the tmux heartbeat keeper and any systemd/cron timer call).
  • editorget / set the command Ctrl+O runs (the worktree path is appended as the final argument).

How session delete is handled

session delete <uuid> is a soft-delete by default: it only marks the database row deleted. The tmux window, git worktrees, and any pending scheduled commands are left untouched — the running TUI cleans those up on its next sync, and the session stays recoverable with session restore <uuid> (the TUI's Ctrl+U / Ctrl+Z undo). Restore revives the metadata; the TUI re-spawns a fresh window for it.

Pass --force to tear down the session's runtime resources in the same call — for headless cleanup when no TUI is running to observe the deletion. A forced delete also:

  • kills the tmux window,
  • removes the session's git worktrees (the underlying repos are left intact),
  • removes the multi-repo symlink workspace, if any (only the symlinks — never the linked repos), and
  • disables any send automations that target the session.

Teardown is best-effort : individual tmux/worktree failures are recorded in the JSON report ( killed_window , removed_worktrees , worktree_errors , disabled_automations ) but never abort the delete. The DB row is always soft-deleted last, so even a forced delete stays restorable — it just re-spawns from a clean slate.