Architecture#
flowchart LR
subgraph disk[Agent data on disk]
C[(~/.claude)]
X[(~/.codex)]
O[(opencode storage)]
end
subgraph core[optimus core]
P[providers] --> I[index + parse cache]
I --> U[usage · blocks · budgets]
R[ratelimits] --> U
H[handoff]
M[mux: tmux -L optimus]
end
disk --> P
TUI[Terminal dashboard<br/>Bubble Tea] --> core
CLI[CLI] --> core
WEB[Web dashboard<br/>HTTP API + xterm.js] --> core
WEB <-. websocket + pty .-> M
M --> A1[claude]
M --> A2[codex]
M --> A3[opencode]
M --> A4[…]
| Package | Responsibility |
|---|---|
internal/providers |
one adapter per agent: discover sessions, parse transcripts into normalized sessions and hourly per-model token buckets, build launch and resume arguments |
internal/index |
runs providers in parallel and caches results (gob, keyed by size and modification time); matches windows to sessions |
internal/pricing |
model price table with longest-prefix matching and config overrides |
internal/usage |
grouping by day, model, agent and project; 5-hour blocks; budgets; projects |
internal/ratelimits |
Claude quota snapshots from the status line, Codex quota from rollouts |
internal/mux |
the tmux backend: spawn, list, capture, send, keys, private browser views, state detection |
internal/agentstate |
states the agents report through hooks, merged with what the screen shows |
internal/outside |
agents running outside optimus: found by process, linked in place or taken over |
internal/dirs |
folders to start a session in: every project under home, and path completion |
internal/handoff |
context documents within a token budget, optional condensing by an agent |
internal/tui |
the terminal dashboard |
internal/web |
the browser dashboard: JSON API, token auth, websocket terminals, embedded static UI |
internal/cli |
subcommands, installer helpers, status line |
Design notes#
- Read-only on agent data. optimus never writes to an agent's history. It only reads files, and it launches agents through their own CLIs.
- Hour buckets, not raw events. Sessions store per-hour, per-model usage, enough for daily charts, 5-hour blocks and budgets, and small enough to cache thousands of sessions.
- Dedup at the source. Claude Code writes one line per content block of a response, and Codex reports cumulative counters. Providers dedupe by message id or take deltas, so nothing is counted twice.
- tmux as the process supervisor. Agents outlive every UI. Optimus windows carry
@optimus_agent,@optimus_cwdand@optimus_sessionoptions; background services (the web dashboard) run in a separateoptimus-svcsession that is never listed as an agent. - One cgroup per agent. On Linux with a systemd user manager, each agent runs in its own
optimus-agent-*.scope(systemd-run --user --scope, which execs in place, so the pane's process is still the agent). The out-of-memory killer takes whole cgroups: without scopes one runaway agent ended every session at once, and restarting whatever started tmux took them all down.OPTIMUS_NO_SCOPE=1turns it off. - The window follows the session. A window's
@optimus_sessionis set at launch and updated by the agent's hooks when it switches session (/clear,/resume, a fork), so cost, transcript and handoff follow what's actually running. A window that knows its session never guesses one from its folder. - Browser views are grouped sessions. Each terminal tab gets its own current window and size, and is removed when the websocket closes. Leftovers from a crash are swept on startup.
- Handoffs by reference. Agents receive a short prompt pointing to the document on disk, so the same mechanism works for every agent.
Built with#
tmux, Bubble Tea and Lip Gloss, xterm.js, coder/websocket and creack/pty. The demo is recorded with VHS, and this site is built with Material for MkDocs.