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 onCtrl+Ffork. -
resume_latest—truemeans 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]]
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]]
name = "codex"
command = "codex"
resume_args = ["resume", "--last"]
fork_args = ["fork", "--last"]
resume_latest = trueantigravity #
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]]
name = "antigravity"
command = "agy"
resume_args = ["--continue"]
resume_latest = trueopencode #
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]]
name = "opencode"
command = "opencode"
resume_args = ["--continue"]
fork_args = ["--continue", "--fork"]
resume_latest = trueaider #
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]]
name = "aider"
command = "aider"
resume_args = ["--restore-chat-history"]
resume_latest = truecopilot #
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]]
name = "copilot"
command = "copilot"
resume_args = ["--continue"]
resume_latest = truevibe #
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]]
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]]
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]]
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]]
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]]
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.