OpenCode CLI plugin that mirrors agent status to iTerm2 3.7+ Session Status and its native tab progress indicator: a subtitle below the tab name, a colored dot, animated loading while working, and detail text for the Session Status tool and Cockpit.
The main tab title shows Session title · folder, for example Fix login bug · oc-iterm2. The suffix is the active session's directory name, falling back to OpenCode's current location. It follows the active session and title changes; the home screen shows OpenCode · folder. The previous titles are saved and restored when the plugin stops.
This uses OSC 0, which updates both iTerm2's session name and tmux's pane title
(including tmux -CC; tmux ignores OSC 1). Select Session Name under
Settings > Profiles > General > Title to display it, and remove any manual
tab-title override. Set the plugin's title: false option to disable this.
Set "terminal": { "title": false } in OpenCode's cli.json so its built-in
title writer does not overwrite the plugin's title.
It reports the same lifecycle Claude Code's integration shows, plus failures:
| State | Meaning | Dot | Progress |
|---|---|---|---|
waiting |
permission, form, or question needs your input | red | paused |
working |
this session or its subagents are running | theme accent (fallback #ec5b2b) |
animated |
error |
last run failed (sticky until the next run) | red | error |
idle |
nothing running | green (#00ff00) |
cleared |
When multiple agents are running, the tab subtitle includes the count, for example working · 3 agents. This counts the main session (when running) and its running subagents. The count also appears in Session Status/Cockpit detail; the subtitle returns to working when only one agent remains active.
Progress uses OSC 9;4,
separately from the OSC 21337 status text and dot. iTerm2 controls the progress
colors and animation; no percentage is estimated. Progress is also cleared on
plugin shutdown. Set progress: false to emit only Session Status updates.
- iTerm2 3.7 or later (stable release with Session Status).
- OpenCode V2 (
opencode2beta with CLI plugin support). - Recommended: run tmux through iTerm2's native integration (
tmux -CC) so each pane gets its own tab status. Plain tmux works too via DCS passthrough (see below), but all panes in one iTerm2 tab share that tab's status.
npm install @pfoundation/oc2itermThen register it in ~/.config/opencode/cli.json:
{ "plugins": ["@pfoundation/oc2iterm"] }Loading is via directory discovery: OpenCode picks up the package's
tui.ts entrypoint (a re-export of src/tui.ts).
# 1. Link the plugin into OpenCode's global plugin directory.
ln -s ~/dev/oc-iterm2 ~/.config/opencode/plugins/oc-iterm2
# 2. Register it in ~/.config/opencode/cli.json (path is relative to that dir):
# { "plugins": ["./plugins/oc-iterm2"] }
# 3. Restart the OpenCode TUI.Loading is via directory discovery: OpenCode picks up
~/.config/opencode/plugins/oc-iterm2/tui.ts (a re-export of src/tui.ts).
The cli.json entry documents the dependency; on some betas local-path
cli.json entries alone are silently ignored, so the root tui.ts is what
makes the plugin load. Because the install is a symlink, edits under
~/dev/oc-iterm2 are picked up when the TUI reloads plugins.
The plugin is CLI-only: it runs in the terminal process, so it also works when the TUI connects to a remote OpenCode server.
All options are optional; set them in cli.json with the object form:
{
"plugins": [
{
"package": "./plugins/oc-iterm2",
"options": {
"title": true,
"text": { "working": "working", "waiting": "waiting", "idle": "idle", "error": "error" },
"dot": {
"waiting": "#ff5f57",
"idle": "#00ff00",
"error": "#ff0000"
},
"textColor": "",
"detail": true,
"progress": true,
"tmux": "auto",
"tmuxLevels": 1,
"pollMs": 2000,
"forceMs": 30000,
"debug": false
}
}
]
}| Option | Default | Notes |
|---|---|---|
text |
above | Subtitle per state. Lowercase matches iTerm2's default priority sort. |
title |
true |
Set the main tab title to Session title · folder using OSC 0. |
dot |
above | #rrggbb overrides per state; working follows the theme by default. |
textColor |
"" |
Subtitle text color; empty keeps iTerm2's default. |
detail |
true |
Show permission action, subagent count, or error in tool/Cockpit. |
progress |
true |
Native tab progress: animated working, paused waiting, error, clear idle. |
tmux |
auto |
auto adds a DCS-wrapped copy when $TMUX is set. |
tmuxLevels |
1 |
Wrap depth for nested tmux sessions. |
pollMs |
2000 |
Recompute cadence (session switches, drift). Min 250. |
forceMs |
30000 |
Force re-emit cadence (recovers after tmux reattach). Min 1000. |
debug |
false |
Append to /tmp/opencode/oc-iterm2.log. |
The working dot uses OpenCode's resolved theme.hue.accent[500] color and
refreshes on the next status update or poll (by default within 2 seconds of a
theme change). If that color is unavailable, it uses #ec5b2b. Set
dot.working to a hex color to override the theme.
OC_ITERM2_DEBUG=1 in the TUI's environment enables debug logging without
passing options (useful when cli.json only lists the plugin by path).
The plugin emits raw OSC 21337 status and OSC 9;4 progress sequences plus,
when $TMUX is set, a
DCS-wrapped copy (ESC Ptmux; … ESC \) that tmux forwards to iTerm2. Enable
forwarding in ~/.tmux.conf:
set -g allow-passthrough on
(tmux 3.3+; all instead of on if hidden panes should also update the tab.)
- View every session:
View > Toolbelt > Session Status, or the floatingWindow > Cockpit(⌥⇧⌘C). - Priority sort: the tool sorts
waiting > working > idleby default. To rank failures the same way, adderrorto the priority list in the tool's gear-menu settings. - Dot only: the same gear menu can hide subtitle text while keeping dots.
- Notify on change:
Window > Notify on Status Change(⇧⌘X) alerts when any session in the window changes state.
Emit status and progress updates from your real terminal setup to verify rendering:
bun scripts/probe.ts working "2 agents"
bun scripts/probe.ts waiting "permission · edit"
bun scripts/probe.ts error "rate limited"
bun scripts/probe.ts idle
bun scripts/probe.ts clearbun install
bun test # unit + plugin integration tests
bunx tsc --noEmitLayout: tui.ts (discovery entrypoint, re-exports src/tui.ts),
src/iterm.ts (OSC 21337 and OSC 9;4 encoding), src/state.ts (options and state
derivation), src/tui.ts (plugin entry, { id, setup } per the V2 TUI
loader contract).