Built-in agents

Thurbox is agent-neutral : it knows nothing about a coding agent's model, prompts, permissions, or tools — only how to launch the CLI and how that CLI resumes, forks, and reports status. Every agent is data , declared in ~/.config/thurbox/agents.toml . The ten entries below are what Thurbox seeds on first run ; each block is the recommended configuration, ready to copy.

No model is ever passed. Each agent runs with its own default config . To pin a model or any other flag, add it to args (always passed) — e.g. args = ["--model", "opus"] . Keep the default entry and add a second [[agents]] variant if you want both.

Overview #

Each [[agents]] entry carries a command plus optional argument-template groups that Thurbox appends only when their driving value is present , substituting the thurbox-generated session id for {id} :

  • args — always passed (bake a model or any flag here).
  • new_session_args — emitted on a fresh spawn (used to pin a session id).
  • resume_args — emitted on restart/resume.
  • fork_args — emitted on Ctrl+F fork.
  • resume_latesttrue means resume/fork target the last session in the launch directory (id-less flags), for CLIs that can't pin a session id.

Selection precedence is fork > resume > new-session ; static args always follow. ID models matter: agents that pin a thurbox id (claude, pi) resume/fork that exact session , omp is path-pinned (thurbox maps its id to a fixed session file), and the rest are id-less and resolve "the last session in this directory" themselves. Status reporting is wired separately by the built-in hooks extension .

At a glance #

Agent Command Resume Fork ID model Status
claude claude by id yes pinned full
codex codex last in dir yes id-less no blocked
antigravity agy last in dir id-less full
opencode opencode last in dir yes id-less full
aider aider chat history id-less blocked only
copilot copilot last in dir id-less full
vibe vibe — (fresh) none no blocked
pi pi by id yes pinned full
omp omp by session file path-pinned full
shell bash -i none none

"Status" is what the session-list dot can reflect (see the per-agent coverage matrix ). The default agent is claude ; change it with default = "<name>" at the top of the file.

claude #

Anthropic's Claude Code . Accepts a thurbox-generated session id at creation, so it resumes and forks that exact session by id.

Resume: by id Fork: yes Status: full (idle/working/blocked/done)

agents.toml
[[agents]]
name = "claude"
command = "claude"
resume_args = ["--resume", "{id}"]
fork_args = ["--resume", "{id}", "--fork-session"]
new_session_args = ["--session-id", "{id}"]

codex #

OpenAI's Codex CLI . It can't pin or report a session id, so resume/fork target the most recent session in the launch directory (resume_latest = true). Thurbox keeps that directory stable across restart (same cwd) and single-repo fork (child reuses the parent cwd).

Resume: last in dir Fork: yes Status: no blocked (experimental)

agents.toml
[[agents]]
name = "codex"
command = "codex"
resume_args = ["resume", "--last"]
fork_args = ["fork", "--last"]
resume_latest = true

antigravity #

The agy CLI (the Gemini CLI successor). Resumes the latest session in the launch directory via --continue ; it has no fork, so Ctrl+F starts a fresh session.

Resume: last in dir Fork: — Status: full (idle/working/blocked/done)

agents.toml
[[agents]]
name = "antigravity"
command = "agy"
resume_args = ["--continue"]
resume_latest = true

opencode #

opencode . --continue resumes the last session in the cwd; --fork branches it.

Resume: last in dir Fork: yes Status: full (idle/working/blocked/done)

agents.toml
[[agents]]
name = "opencode"
command = "opencode"
resume_args = ["--continue"]
fork_args = ["--continue", "--fork"]
resume_latest = true

aider #

aider restores the chat-history file in the cwd; it has no separate session id and no fork. Its only lifecycle callback is "waiting for input", so the status dot reflects blocked only.

Resume: chat history Fork: — Status: blocked only

agents.toml
[[agents]]
name = "aider"
command = "aider"
resume_args = ["--restore-chat-history"]
resume_latest = true

copilot #

GitHub Copilot CLI (the copilot command). Resumes the most recent session in the launch directory via --continue ; it can't pin or report a session id and has no fork.

Resume: last in dir Fork: — Status: full (experimental)

agents.toml
[[agents]]
name = "copilot"
command = "copilot"
resume_args = ["--continue"]
resume_latest = true

vibe #

Mistral's vibe CLI. It declares no resume group, so it always starts fresh on restart — the live tmux process is what carries its state across TUI restarts. No fork.

Resume: — (fresh) Fork: — Status: no blocked (experimental)

agents.toml
[[agents]]
name = "vibe"
command = "vibe"

pi #

The pi.dev CLI. Like claude, it accepts a thurbox-generated session id at creation, so it resumes/forks by that exact id. Sessions live under ~/.pi/agent/ , organized by working directory.

Resume: by id Fork: yes Status: full (experimental)

agents.toml
[[agents]]
name = "pi"
command = "pi"
resume_args = ["--session-id", "{id}"]
fork_args = ["--fork", "{id}"]
new_session_args = ["--session-id", "{id}"]

omp #

Oh My Pi (the omp command) is Pi-compatible but generates its own internal session id, so it can't accept thurbox's. Instead it takes a session file path : thurbox maps its UUID to a deterministic JSONL under OMP's default root (--session <file> on create, --resume on the same path to restore), so restart reattaches the exact session. The {home} token expands to the resolved home dir at spawn time (thurbox, not the shell — args are POSIX-quoted, so a literal ~ never expands), and it translates onto a remote/WSL home too. No fork — OMP can't pin a fork's target file, so Ctrl+F starts fresh.

Resume: by session file Fork: — Status: full (experimental)

agents.toml
[[agents]]
name = "omp"
command = "omp"
resume_args = ["--resume", "{home}/.omp/agent/sessions/thurbox-{id}.jsonl"]
new_session_args = ["--session", "{home}/.omp/agent/sessions/thurbox-{id}.jsonl"]

shell #

The one seeded entry that is not a coding agent: the platform's own interactive shell. It exists so a session can be anything — you run whatever you like in it, and an external driver can start its own tool with its own flags rather than asking Thurbox to model them. It is the ready-made form of thurbox-cli session create --command , and the only built-in whose command differs by platform: native Windows runs psmux and PowerShell rather than tmux and bash.

args = ["-i"] is load-bearing rather than decoration. A plain bash in a pane executes what is sent to it but renders no prompt and no echo , so anything reading the screen to decide whether the session is ready sees a blank pane that is nonetheless working.

It declares no resume_args or fork_args , and that absence is the statement: a shell has no conversation. session restart replays its recipe in the same directory (a shell barely notices — its history and cwd live on disk), session fork gives you a second shell beside it, and session create --resume silently starts fresh rather than attaching to anything (only a raw --command session refuses --resume outright). Nothing wires status hooks for it either, so a shell session reports no state until something in it calls thurbox-cli session signal — which anything in the pane can, since THURBOX_SESSION is in its environment.

Resume: — Fork: — Status: none

agents.toml
[[agents]]
name = "shell"
command = "bash"
args = ["-i"]

# On native Windows the seed writes this instead:
# command = "powershell"
# args = ["-NoLogo"]

Adding your own #

Any CLI works — add an [[agents]] entry with a command and whichever *_args groups it supports. No recompile.

agents.toml
[[agents]]
name = "my-agent"             # shown in the new-session picker
command = "my-agent-cli"      # the executable on your PATH
args = []                     # always passed (put a model flag here)
resume_args = []              # appended on resume, with {id} substituted
fork_args = []                # appended on Ctrl+F fork, with {id} substituted
new_session_args = []         # appended on a fresh spawn, with {id} substituted
resume_latest = false         # true = id-less "resume last session in cwd"
# hook_schema = "claude"      # optional: name the hook FAMILY this CLI speaks so
#                             #   the hooks extension wires status under this name

Set hook_schema = "claude" on a rebranded agent (one whose command runs claude under a different name) so it inherits claude's status-hook wiring. See the agents.toml reference for the full field list and the hooks page for how status is wired.