Skip to content

Supported Code Agents

Otty integrates with the coding-agent CLIs you run yourself. You keep using the agent exactly as you would in any terminal — Otty plugs into it so the tab badges, notifications, history, resume, and (where the agent supports it) fork all work. The available features depend on the agent, as shown below.

AgentCommandHow Otty connectsResumeForkHistoryUsageQuota
Claude CodeclaudeHooks in ~/.claude/settings.json
CodexcodexHooks in ~/.codex/hooks.json (+ hooks = true in config.toml)
OpenCodeopencodePlugin in ~/.config/opencode/plugins
Cursor CLIagentHooks in ~/.cursor/hooks.json
Kimi CodekimiHooks in ~/.kimi-code/config.toml (TOML [[hooks]])
PipiExtension in ~/.pi/agent/extensions
ompompExtension in ~/.omp/agent/extensions
Grok BuildgrokHooks in ~/.claude/settings.json (Grok reads it too)
ReasonixreasonixHooks in ~/.reasonix/settings.json
CodeBuddy CLIcodebuddyHooks in ~/.codebuddy/settings.json
Google Antigravity CLIagyHooks in ~/.gemini/config/hooks.json
GitHub Copilot CLIcopilotHooks in ~/.copilot/hooks/
Any other agentyour CLICustom integration: otty state:<name> from your own hook

Installation is one click: the first time Otty needs the integration it asks to install the hook or plugin into that agent's own config — it won't touch your other settings. See Setup to install, manage, or remove it.

Running something that isn't on this list? It can still report itself to Otty and get the badges and notifications — see Custom agents.

Platform support

The built-in agent catalog, lifecycle hooks, session resume and supported fork commands are available on macOS, Linux and Windows. History discovery covers Claude Code, Codex, OpenCode, Cursor, Kimi, pi and omp, including Codex's CODEX_HOME and Kimi's KIMI_CODE_HOME overrides. OpenCode history supports both the legacy file store and the current SQLite database; Otty reads the database without modifying it and stores history pointers in its own user cache.

Linux and Windows expose session and prompt history through Open Quickly. Session usage follows the table above; plan quota is available for Claude, Codex and omp. Claude's plan file can be opened from the agent actions. Automatic restore keeps the saved terminal output when Claude's transcript is missing or empty, or when the session is still running as a background job.

Automatic permission approval is a separate platform feature: macOS has the AI reviewer, Linux currently uses configured tool rules, and Windows does not yet provide automatic approval.

Usage and plan quota

The last two columns are about numbers rather than control: how much a session has spent, and how much of your plan is left. They come from what each agent already records, so what you get differs per agent — which is why they are tracked separately from Resume and Fork.

Usage is the session's own accounting, shown in the agent's group in the details panel (⌘I): how full the context window is, the running token total, and — for the agents that compute one — what the session cost. It is read out of the log that agent already writes to disk. There is nothing to enable, nothing leaves your machine, and an agent that logs none of it simply shows no numbers.

Quota is your plan's remaining allowance, and only Claude Code, Codex and omp can answer for it. It is a separate column because it is a separate kind of read: Otty runs that agent's own CLI in the background — claude -p "/usage", codex app-server, omp usage --json — every few minutes, using the login the CLI already has. All three are on out of the box; Show Plan Quota on the agent's card under Settings (⌘,) → Agents turns one off.

The agents with a in Quota aren't being neglected: OpenCode and pi bill per use and publish no ceiling to draw a bar against, and the rest expose no way to ask. See Usage readout for what each agent reports, and for how the bars are coloured.

Custom launch commands

Expand an agent under Settings → Integrations to override the command Otty uses when it starts, resumes, or forks that agent. This is useful for wrappers, absolute executable paths, and global flags. Otty appends the agent-specific session arguments, so enter claude --dangerously-skip-permissions, not a full claude --resume <id> command. Leave the field empty for the built-in default.

The same override can be written in the config file:

ini
agent-command = claude=claude --dangerously-skip-permissions
agent-command = codex=/opt/homebrew/bin/codex --profile work

Claude Code

Anthropic's Claude Code CLI. Otty adds hook entries to ~/.claude/settings.json that report each turn's state (processing, idle, awaiting input).

  • Resume reopens a past conversation with claude --resume <id>.
  • Fork branches it into a new session with claude --resume <id> --fork-session.
  • Transcripts live as JSONL under ~/.claude/projects/…, so History can search and reload them.

Codex

OpenAI's Codex CLI. Otty installs hooks into ~/.codex/hooks.json.

  • Codex only runs hooks when the hooks feature is enabled in ~/.codex/config.toml. Otty turns it on when it installs the hooks; if it ever gets switched off, Otty offers a one-click re-enable (then restart Codex in that tab).
  • Resume uses codex resume <id>; Fork uses codex fork <id>.

OpenCode

The self-hosted OpenCode agent. Instead of hooks, Otty installs a small plugin into ~/.config/opencode/plugins.

  • Resume uses opencode --session <id>; Fork uses opencode --fork --session <id>.
  • Heads-up: OpenCode doesn't announce a session when you switch to it via /sessions — Otty only picks it up once you send a message in that session. If a freshly-switched tab looks unlinked, type something and it connects.

Cursor CLI

Cursor's terminal agent, launched as agent (cursor.com/docs/cli). Otty adds entries to Cursor's JSON hooks in ~/.cursor/hooks.json that report each turn's state.

  • Resume reopens a past conversation with agent --resume <chatId>.
  • Fork is not offered — Cursor has no CLI fork command, so the Fork action stays greyed out.
  • Transcripts live under ~/.cursor/projects/…/agent-transcripts/, so History can search and reload them.

Kimi Code

The kimi CLI (moonshotai/kimi-code). Its config home is ~/.kimi-code (override with $KIMI_CODE_HOME). Kimi exposes Claude-Code-style lifecycle hooks declared in TOML, so Otty adds an [[hooks]] entry to ~/.kimi-code/config.toml.

  • Resume uses kimi --session <id>.
  • Fork is not offered.
  • Sessions are stored under ~/.kimi-code/sessions/…, so History can reload them.

Pi and omp

Pi (pi) and omp (omp) share one codebase — omp is a rebrand of pi — and both load TypeScript extensions the way OpenCode loads plugins. Otty installs one extension into ~/.pi/agent/extensions or ~/.omp/agent/extensions that reports each turn's state.

  • Resume reopens a specific session with pi --session <path> (omp --session <path>).
  • Fork branches it into a fresh session with pi --fork <path> (omp --fork <path>).
  • Like OpenCode, pi/omp report the session id through the extension rather than a per-process file, so a freshly-switched tab links up once the agent emits its next lifecycle event.

Grok Build

xAI's grok CLI (x.ai/news/grok-build-cli). Its config home is ~/.grok (override with $GROK_HOME), but its hooks don't live there: the only user-wide hooks Grok reads are the ones in Claude Code's ~/.claude/settings.json, which it loads as a compatibility layer. That's where Otty installs the Grok integration — as its own entries, alongside (never on top of) anything already in that file. Grok's own hooks/ folder is per-project (.grok/hooks/ inside a repo) and a hook Otty put in ~/.grok/hooks/ would simply never run.

  • Resume reopens a past conversation with grok --resume <id>.
  • Fork branches it into a new session with grok --resume <id> --fork-session.
  • Session history isn't wired up yet, so Grok sessions don't appear in History or Open Quickly.
  • Because that file is shared, every agent's Otty hook in it can be started by the other agent's runner. Each one checks who invoked it and stands down when it isn't the right agent, so the badge always names what's actually running.
  • Grok needs to trust a folder before it runs any hook there (it asks the first time, and /hooks-trust does it by hand). Until you accept, the tab shows no badge.

Reasonix

The DeepSeek-native reasonix CLI (reasonix.io). Its config home is ~/.reasonix (override with $REASONIX_HOME). Reasonix runs shell commands on its lifecycle events, so Otty adds its entries to the hooks section of ~/.reasonix/settings.json and leaves everything else in that file untouched.

  • Resume reopens a past conversation with reasonix --resume <id>.
  • Fork continues in a copy with reasonix --resume <id> --copy, leaving the original transcript alone.
  • Reasonix also reports when it's waiting for your approval, so the tab shows the awaiting-input badge — not just processing and done.
  • Reasonix loads hooks when a session starts, so restart reasonix in that tab after installing.
  • settings.json is shared with Reasonix's own Hooks editor, so Otty won't rewrite it if it can't read it. If Install won't stick, the file has a syntax error — fix it (Reasonix ignores your hooks too while it's broken) and install again.
  • Resume looks up the conversation in the session store of the directory you started in, so run it from the same project directory.
  • Session history isn't wired up yet, so Reasonix sessions don't appear in History or Open Quickly.

CodeBuddy CLI

CodeBuddy CLI runs as codebuddy. Otty adds its lifecycle hooks to ~/.codebuddy/settings.json, preserving existing settings and hooks.

  • Resume uses codebuddy --resume <id>.
  • After installing hooks, open CodeBuddy's /hooks panel to review and activate external changes. On Windows, CodeBuddy runs its hooks through Git Bash.

Google Antigravity CLI

Antigravity CLI runs as agy. Otty adds a named group to ~/.gemini/config/hooks.json to report processing and completion. A stop with background tasks still running keeps the processing badge active.

GitHub Copilot CLI

GitHub Copilot CLI runs as copilot. Otty installs a hooks file under ~/.copilot/hooks/, or $COPILOT_HOME/hooks/ when configured. It reports turn state and actual permission or input prompts; unrelated notifications do not set the awaiting-input badge.

Otty does not yet offer transcript history, usage/quota readouts, or a Fork action for these three integrations. Their own interactive commands remain available inside the terminal.

Custom Agents

The list above is what Otty ships adapters for — it isn't the limit. The tab badges and notifications are all driven by one CLI call, so any coding agent that can run a command when a turn starts and ends plugs into the same UI, with no change on Otty's side:

bash
otty state:myagent state=processing agent-pid=$$ session-id=abc123 label="My Agent"
otty state:myagent state=idle       agent-pid=$$ session-id=abc123 label="My Agent"

The name after state: is the agent id. An id Otty ships an adapter for (claude, codex, …) gets the full integration described above; any other id is treated as a custom agent — it drives the lifecycle badge and notifications under the name it reports, and nothing else.

The otty command has to be on your PATH: install it from Settings → Shell → Install CLI (see Install the CLI).

Arguments

ArgumentRequiredMeaning
state=yesprocessing — a turn just started · idle — the turn finished · awaiting — the agent is waiting for your approval or input · error — the turn failed
agent-pid=on the first eventPID of the agent process, used to pin the event to a pane. In a hook script "$PPID" is the agent that invoked it; if your agent calls Otty directly, pass its own pid.
session-id=recommendedA stable id for the conversation. Once a pane has seen it, later events carrying the same id land on that pane even without agent-pid.
label=optionalDisplay name for badges and notifications. Defaults to the capitalized id, so state:myagent reads as "Myagent".

How Otty picks the pane

Otty matches an event to a pane by process tree: the reported agent-pid has to be a descendant of some pane's shell. That's deliberate — an event whose pid belongs to no pane is dropped, so the same agent running outside Otty (a desktop app, an editor extension) never badges an unrelated tab.

Built-in agents also have a cwd + process-name fallback, because Otty knows what their binaries are called. A custom agent has no such fallback, so its first event must carry agent-pid, otherwise there's nothing to match on and the call reports that no tab was found.

What a custom agent gets

  • The processing / awaiting / done tab badges, and the Dock progress spinner.
  • System notifications when a task completes and when the agent starts waiting for you.
  • Correct ordering under Updated Time tab sorting, and keep-awake while a turn runs.

All of it honours the same per-tab switches as the built-in agents, so a tab whose agent badges or notifications are turned off stays quiet — see Notifications.

Not included: Resume, Fork, History, and auto-approve stay adapter-only. They need Otty to know how to relaunch the agent, where it stores transcripts, and which keystrokes answer a permission prompt — none of which a state report can carry.

Example: a hook script

Most agents can run a script on lifecycle events. Point them at something like this — it's the shape of Otty's own bundled hooks:

sh
#!/bin/sh
# $1 = processing | idle | awaiting
otty state:myagent \
  state="$1" \
  agent-pid="$PPID" \
  session-id="$MYAGENT_SESSION_ID" \
  label="My Agent" 2>/dev/null &

Background it and swallow errors, as above: reporting state must never block — or break — your agent when Otty isn't running.

Resume without an integration

An agent that wants its sessions to survive a terminal restart can adopt the Terminal Resume Protocol (OSC 88). It's a vendor-neutral, open spec, so any tool that emits it gets resume in Otty without a bespoke integration.

Want your agent supported as a built-in, or building one that should plug in? Get in touch at otty@appmakes.io.

See also

Otty