Skip to content

Commit c0a6dc3

Browse files
committed
feat(tui): add sub agents status with recursive descendant count
Show active/total count of all descendant sub-agents (not just direct children) in the prompt status bar, with cycle-safe BFS traversal.
1 parent 5c5069b commit c0a6dc3

1 file changed

Lines changed: 35 additions & 0 deletions

File tree

  • packages/opencode/src/cli/cmd/tui/component/prompt

packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,35 @@ export function Prompt(props: PromptProps) {
102102
const dialog = useDialog()
103103
const toast = useToast()
104104
const status = createMemo(() => sync.data.session_status?.[props.sessionID ?? ""] ?? { type: "idle" })
105+
const subagents = createMemo(() => {
106+
if (!props.sessionID) return { total: 0, active: 0 }
107+
const byParent = new Map<string, (typeof sync.data.session)[number][]>()
108+
for (const s of sync.data.session) {
109+
if (!s.parentID) continue
110+
const list = byParent.get(s.parentID) ?? []
111+
list.push(s)
112+
byParent.set(s.parentID, list)
113+
}
114+
const descendants: (typeof sync.data.session)[number][] = []
115+
const queue = [props.sessionID]
116+
const visited = new Set<string>()
117+
while (queue.length > 0) {
118+
const pid = queue.pop()!
119+
if (visited.has(pid)) continue
120+
visited.add(pid)
121+
const children = byParent.get(pid)
122+
if (!children) continue
123+
for (const c of children) {
124+
descendants.push(c)
125+
queue.push(c.id)
126+
}
127+
}
128+
const active = descendants.filter((d) => {
129+
const st = sync.data.session_status[d.id]?.type
130+
return st === "busy" || st === "retry"
131+
}).length
132+
return { total: descendants.length, active }
133+
})
105134
const history = usePromptHistory()
106135
const stash = usePromptStash()
107136
const command = useCommandDialog()
@@ -1398,6 +1427,12 @@ export function Prompt(props: PromptProps) {
13981427
</Switch>
13991428
<text fg={theme.text}>
14001429
{keybind.print("command_list")} <span style={{ fg: theme.textMuted }}>commands</span>
1430+
<Show when={subagents().total > 0}>
1431+
<span style={{ fg: subagents().active > 0 ? theme.warning : theme.textMuted }}>
1432+
{subagents().active > 0 ? " ⚡" : " "}
1433+
{subagents().active}/{subagents().total} sub agents
1434+
</span>
1435+
</Show>
14011436
</text>
14021437
</Match>
14031438
<Match when={store.mode === "shell"}>

0 commit comments

Comments
 (0)