Agent Teams in the TUI¶
There is no separate team view. A team you start in the TUI runs inside your current conversation — the conversation's agent becomes the coordinator (see AI Assistant → Working with a team) — and the same chat window shows it live: a status panel below the input, a full task board on demand, and a focus mode for stepping into any teammate's own thread. An earlier build had a dedicated multi-window :team view driven by a separate scripted session; that view is gone. :team <slug> still works, but now it just asks the conversation's agent to start that team recipe.
Starting a team¶
Either ask for it directly:
or use the :team <slug> shorthand, which sends the conversation an ask in those words for that recipe:
:team <slug> is ordinary text once sent — it appears in the transcript like any other turn, and the agent decides how to start the team (team_start) just as it would from a typed-out request. If you're not in the AI chat view, it switches you into one first so the turn lands somewhere visible.
Bare :team (no slug) doesn't start anything — there's no roster to list from inside the TUI. It prints a hint instead:
:team <slug> asks this agent to start that team recipe and coordinate it.
Run 'bnerd team list' to see the available recipes.
Run bnerd team list in a shell to see what recipes your mission repo defines.
The live team panel¶
While a chat-driven team is running, a panel appears below the input showing every teammate's live state, one row per member:
○ conversation [driver]
▶ ● dev·go-cli-dev implementing /networks handler 2/1 tasks 4.2k tok ~$0.08
└ explore_agent scanning cmd/ for existing patterns
◐ qa·go-cli-dev-qa waiting on your approval 0/0 tasks 1.1k tok ~$0.01
✓ docs-engineer done 1/1 tasks 0.9k tok ~$0.01
○ 4 idle
tasks 3/7 done · 1 blocked · 1 gate open — ctrl+t board
The first row is always conversation — the main chat itself, not a teammate. It has no task or cost columns (those are the conversation's own, already on the chat status line), it is never faded or folded into the ○ N idle summary, and it carries the [driver] tag whenever coordination has not been handed to a delegated coordinator — so exactly one row on the panel always names who is driving. It shows ◐ waiting on you when an approval or question is parked on the conversation.
Each teammate row is <glyph> <name>·<role> <activity> <claimed>/<done> tasks <tokens> tok [~$cost]. When a teammate was spawned under its own role slug — the usual case for an always-on member — the name and role collapse to one: docs-engineer, not docs-engineer·docs-engineer.
The tail reads left to right: tasks this member has claimed over tasks it has completed, then the tokens its thread has spent, then the cost. The cost is prefixed ~ because it is an estimate — a per-member approximation derived from token counts, not a billing figure. Use your provider's own reporting for anything that has to be exact.
| Glyph | Meaning |
|---|---|
● | working |
◐ | waiting on you |
○ | idle |
✓ | done |
✗ | failed |
A subagent a teammate spawned (sub_agent, explore_agent, kube_agent) nests under its parent as └ <label> <activity>.
Attention management keeps the panel from becoming a wall of idle rows:
- A row idle for 30+ seconds fades to a dimmer style.
- More than 3 idle rows collapse into a single
○ N idlesummary line instead of listing each one. - Rows waiting on you always render at the top, above working and idle rows, so an approval or question is never buried.
- The panel caps at 8 body lines; anything past that collapses into
… and N more.
The footer summarizes the task board: tasks <done>/<total> done · <N> blocked · <M> gate open — ctrl+t board.
Task board (Ctrl+T)¶
Press Ctrl+T while a chat-driven team is active to open the full task board — every task, not just what fits in the panel:
#1 ✓ add the /networks endpoint · dev · deps:- · gates:1/1@a1b2c3d
#2 ● wire up CLI flags · dev · deps:1 · gates:0/1
#3 ◐ review the handler · qa · deps:1 · gates:0/0 · ⚑approval
Each line is #<id> <status-glyph> <subject> · <owner> · deps:<ids> · gates:<passed>/<total>[@ref] · ⚑approval (the ⚑approval suffix only appears on tasks that require an approval to complete; @<ref> only appears once every declared gate has passed at the same ref). Use ↑/↓ to scroll when there are more tasks than fit on screen. Esc, q, or Ctrl+T again closes the board and returns to the conversation.
Focus mode¶
The panel carries a selection cursor independent of the task board:
Shift+↑/Shift+↓move the cursor between panel rows, wrapping at both ends. The cursor starts on theconversationrow andShift+↑from the top teammate returns to it, so getting back to the main chat is one keypress rather than a lap around the roster.- The cursor follows the row by name. Panel rows re-sort constantly as teammates start waiting, working, or going idle, and the cursor stays on the teammate you put it on instead of on whatever slides into that position. If that teammate leaves the roster, the cursor falls back to the
conversationrow. Enteron an empty input line walks into the selected row: the chat viewport switches to that teammate's own transcript, and the input now addresses that teammate's mailbox directly (ato @<name> >label appears above the input box). Sending a message there is a direct DM — it never touches the conversation's own session. On theconversationrow,Enterwalks back out — the same thingEscdoes.←/→cycle to the previous/next sibling teammate without leaving focus. They skip theconversationrow: cycling siblings should never drop you out of the thread you are reading.Ctrl+Xasks the coordinator to gracefully stop the focused teammate.Escalways exits focus mode back to the conversation. This is unconditional — Esc never interrupts a stream or cancels anything else while you're focused; it only steps you back out. If you want to stop the teammate, useCtrl+Xinstead.
The status line below the input becomes a focus footer while you're focused:
If the conversation itself has something waiting on you while you're inside a teammate's thread, the footer adds a cue: ⚠ conversation needs you. Press Esc to get back and answer it.
Slash commands aren't available while focused — sending one prints a note telling you to press Esc first, rather than running it against the teammate's session by mistake.
Reopening a teammate's thread after the team ends
Focus mode itself only reads a teammate's live thread while the team run is active — once the team ends, focus mode has nothing left to walk into. To go back and read a teammate's history afterwards, use its child session instead: every teammate is recorded as a child of the launching conversation in the global session store at each of its history flush points — when it is stopped, when the team finishes, and on the interrupted flush the exit grace runs — so bnerd sessions list --children <conversation-id> lists it, profile the teammate's role slug and title teammate: <name>, and bnerd sessions show <id> reads it back. A teammate still mid-run between flushes is not yet in that record.
The same listing carries one teammate: lead child: the team-level record (paused/resumed/finished, per-teammate completion lines with tool and token counts, stops, gate mismatches), written when you exit with the team still live. See bnerd sessions.
Delegated coordinator¶
When the conversation hands coordination off to a teammate (team_delegate — see Delegated coordinator), the panel tags that teammate's row [driver]:
The [driver] row is exempt from idle collapse and fade: waiting on its own inbox between events is a delegated coordinator's normal resting state, so collapsing it into the ○ N idle summary would hide exactly the row you want to check to see who's driving.
The ambient status line also names the delegate:
The coordinated by <name> segment only appears while delegated; a non-delegated team's ambient line is unchanged. See AI Assistant → Working with a team for how to delegate and what changes.
Ambient status line¶
When a chat-driven team is running and you're not focused on any teammate, the idle status line below the input (normally the mode badge and hint text) becomes an ambient summary instead:
The waiting-agent segment (· <N> waiting) only appears when at least one teammate is waiting on you. This lets you keep an eye on overall team progress and spend without opening the panel or the board.
A running team also stays visible outside the chat view: switching to a table view (:zones, :k8s, …) doesn't stop the team, and the header shows a chip so it's never silently forgotten in the background — team: N agents running for N teammates, team: 1 agent running for exactly one, and team: running if the roster is momentarily empty (mid-spawn, or everyone stopped) so an orphaned coordinator still gets flagged. The chip is dropped on terminals narrower than 72 columns, and is suppressed in the AI chat view itself since the panel and status line already cover it there.
See also¶
- AI Assistant → Working with a team for how a conversation becomes a coordinator, and how approvals/questions from a teammate surface inline.
- The
bnerd teamCLI for running a team headlessly instead.