opencode-agent-dock
v1.0.0
Published
OpenCode TUI plugin — a Claude-Code-style bottom panel of running subagents with inline keyboard navigation.
Maintainers
Readme
opencode-agent-dock
An OpenCode TUI plugin that adds a Claude-Code-style bottom panel of your running subagents — visible at a glance under the prompt, with inline keyboard navigation to browse them collapsed and open any one.
Subagents normally only surface inline in the chat, and the chat scrolls away from where they were spawned. opencode-agent-dock keeps the active session's subagents pinned to the bottom of the screen, each with its status, elapsed time and token spend.
How it works
active session route
↓
resolve current session
├─ parent session → client.session.children() → keep the RUNNING ones
└─ subagent session → pin the one currently in focus (panel stays up)
↓
app_bottom slot renders the roster: ● title elapsed · tokens
↓
navigation: keymap.intercept catches ↑/↓/Enter BEFORE the prompt textarea
(the same mechanism opencode uses for copy-on-select), so while the
dock is focused the prompt is "locked" and arrows move the cursorFeatures
- Persistent bottom panel — running subagents stay visible under the prompt (Claude-Code-style: plain rows, no panel chrome).
- Per-subagent telemetry — status glyph, elapsed time and total token usage on every row.
- Inline keyboard navigation — browse the list collapsed,
Enteropens the selected subagent's session. - Stays visible inside a subagent — the focused subagent is highlighted; native
←/→between siblings updates it live. - Self-cleaning — finished/cancelled subagents drop out of the panel automatically; it hides when there are none.
- Escape stays native —
Escis never hijacked, so it still cancels subagents.
Install
This is a TUI plugin, so it is configured in tui.json (not opencode.json):
// ~/.config/opencode/tui.json (user) or .opencode/tui.json (project)
{
"$schema": "https://opencode.ai/tui.json",
"plugin": ["opencode-agent-dock"]
}Restart OpenCode after adding it.
Keybindings
| Key | Action |
| --- | --- |
| ctrl+x v — or /subagents | Focus the dock (toggle) |
| ↑ / ↓ | Previous / next subagent |
| Enter | Open the selected subagent's session |
| ↑ from the first row, or ctrl+x v again | Leave the dock |
| Esc | (native) cancel subagents |
The toggle key (<leader>v) can be remapped in tui.json under the agent-dock.toggle command if you prefer a different one.
Why a toggle and not bare
↓? In the parent session the prompt textarea captures arrow keys, and a plugin cannot blur the host prompt.keymap.interceptruns before the textarea, so once the dock is focused the arrows are ours.↓itself is also the prompt's history key, which made it an unreliable trigger.
Architecture
Clean Architecture — dependencies point inward, the domain is pure, and the only place that knows about the opencode SDK / TUI API is the composition root + adapters.
src/
domain.ts pure: Subagent, selection math, formatting (unit-tested)
ports.ts SubagentStore, Logger contracts
sdk.ts SDK Session/SessionStatus -> domain Subagent
constants.ts plugin id, slot name, limits
adapters/
opencode-subagent-store.ts SubagentStore via client.session.children + events
opencode-logger.ts Logger via client.app.log
view/
Dock.tsx Solid render into the app_bottom slot
index.tsx composition root: slot + inline nav (intercept)Develop
npm install
npm test # vitest — domain unit tests
npm run typecheckOpenCode runs on Bun and loads .ts/.tsx natively, so there is no build step for local file-plugin use:
{ "plugin": [["file:///absolute/path/to/opencode-agent-dock/src/index.tsx"]] }License
MIT © Artem Bambalov
