Agent Terminal Protocol
ATP is how Termio hosts any agent CLI — one JSON manifest declaring how to launch it, how it reports status, and how to resume its exact conversation. The agent’s own TUI stays in a real terminal.
Editor protocols re-render your agent inside an editor pane. ATP takes the opposite bet: the agent’s own TUI already is the interface, so it stays in a real terminal, and the protocol standardizes only the thin layer around it — launch, live status, and exact resume. Every agent Termio ships is defined by this same manifest; there is no privileged internal API.
The manifest
One JSON file per agent. This is Termio’s bundled Grok manifest, verbatim:
{
"id": "grok",
"order": 95,
"name": "Grok",
"wire": "grok",
"command": "grok",
"permissionBypassFlag": "--yolo",
"resume": {
"create": "--session-id {id}",
"resume": "--resume {id}",
"storeRoot": "~/.grok/sessions",
"storeMatch": "dir:{id}"
},
"icon": { "vector": "grok" },
"install": "https://x.ai/cli",
"titleStatus": {
"attention": ["Action Required"]
},
"hooks": {
"type": "json",
"file": "~/.grok/hooks/termio.json",
"dialect": "grok",
"conversation": "sessionId",
"events": [
{ "on": "SessionStart", "state": "idle" },
{ "on": "UserPromptSubmit", "state": "working" },
{ "on": "PreToolUse", "state": "working" },
{ "on": "PostToolUse", "state": "working" },
{ "on": "Stop", "state": "done" }
]
}
}| Field | Meaning |
|---|---|
id | Stable identifier. Sessions persist it, so it never changes once shipped. |
name | Display name in the picker and sidebar. |
command | The CLI to launch, resolved on your login shell’s PATH. |
permissionBypassFlag | The vendor’s skip-permissions flag, wired to a one-click toggle. Optional. |
icon | vector (a built-in brand mark), path (your PNG/SVG file), or symbol (an SF Symbol), with an optional tint. |
install | The vendor’s install page, offered when the command isn’t found. Optional. |
order | Position in the agent picker. Optional; omitted manifests sort last. |
skills | The agent’s user-level skills directory ({"dir": "~/.claude/skills"}), which is where Termio writes its session-control skill. Optional; omit it for an agent with no skills ecosystem. |
configHome | The environment variable the agent documents for moving its config tree, and the path that variable replaces ({"env": "CLAUDE_CONFIG_DIR", "path": "~/.claude"}). Set it and Termio installs where the agent actually reads, rather than at the literal default. Optional. |
Status
A session is always in one of four states — working, attention (blocked on
you), done, or idle — shown in the sidebar, the menu bar, and on your
iPhone. The manifest declares how the agent reports them, through three
channels:
| Channel | Role |
|---|---|
hooks | The precise channel: Termio installs the agent’s own hook configuration (JSON, TOML, or a plugin, per dialect) so the agent itself reports each on → state event. When hooks are declared they are the single source of truth. |
titleStatus | Regex rules over the agent’s live terminal title (OSC 0/2) — the in-band signal some agents broadcast. Coexists with hooks and corrects a missed event the instant the title flips. |
status | Screen-classification regexes for agents with no hook system at all. Ignored when hooks are declared. |
hooks.conversation names where the agent’s own session id appears in its hook
payloads (a stdin JSON field for shell hooks, an event key path for plugins).
With it, each status report also carries conversation identity — so when the
agent rotates to a new conversation mid-session (/new, /clear), Termio
re-binds the tab to the live one the moment the next event fires.
Resume
Reopening a session relaunches the agent into the same conversation. Resume is exact-or-nothing: Termio either resumes the precise conversation a tab is bound to, or launches fresh — it never guesses. Two families, inferred from which fields are present:
Pinned id — the CLI accepts a session id at launch. create starts a fresh
conversation under a Termio-minted id and resume continues it; storeRoot +
storeMatch describe the agent’s on-disk session store so Termio can tell the
two apart (creating a duplicate id errors, as does resuming a missing one).
Discovered id — the agent mints the id itself. discover describes the
mechanism, never an agent: where session records live, how a record is read, and
key paths to the id and working directory. A record is either jsonl (the first
line of a log that is itself the transcript) or json (a standalone metadata
file). Termio recovers the id, binds it to the tab, and resumes exactly from
then on.
"resume": {
"resume": "resume {id}",
"discover": {
"root": "~/.codex/sessions",
"format": "jsonl",
"id": "payload.id",
"cwd": "payload.cwd"
}
}Add your own agent
Drop a manifest at ~/.termio/config/agents/<id>.json and restart Termio — it
appears in the picker alongside the built-ins, with the same status dots and
resume behavior. A minimal manifest is just an id, a name, and a command; add
status and resume as the CLI supports them.
The Custom agents guide walks through this end to end — icons, screen-scrape status rules, and overriding a built-in.
Custom agents
Teach Termio about any CLI by dropping a small JSON manifest in ~/.termio/config/agents — give it a name, an icon, and live status detection, and it becomes a first-class agent alongside the built-ins.
Git worktrees
Termio reads your repository’s worktrees straight from git and shows them as a nested branch under the project, so parallel agent work stays isolated.