diff --git a/packages/cli-rs/crates/tui/src/routes/session/messages/list.rs b/packages/cli-rs/crates/tui/src/routes/session/messages/list.rs index a8a68dc0544..6c90c5c1e09 100644 --- a/packages/cli-rs/crates/tui/src/routes/session/messages/list.rs +++ b/packages/cli-rs/crates/tui/src/routes/session/messages/list.rs @@ -226,10 +226,14 @@ impl Transcript { let pending = changes.pending(session); // A tool row waiting on a permission request takes the warning color. let permissions = changes.permissions(session); - if !changes.any_message(session) && !changes.session(session) && !catalogs && !pending && !permissions { + // A subagent row spins while its child session runs. + let children = !changes.status.is_empty() + && tui.data.read(|state| state.family(session).iter().any(|id| id != session && changes.status(id))); + let force = + changes.messages(session) || changes.session(session) || catalogs || pending || permissions || children; + if !force && !changes.any_message(session) { return; } - let force = changes.messages(session) || changes.session(session) || catalogs || pending || permissions; if !force && let Some(messages) = changes.message.get(session) && self.0.patch(tui, session, messages) diff --git a/packages/cli-rs/crates/tui/tests/all/more_tools.rs b/packages/cli-rs/crates/tui/tests/all/more_tools.rs index 34a0e9ed18f..916cb417ab2 100644 --- a/packages/cli-rs/crates/tui/tests/all/more_tools.rs +++ b/packages/cli-rs/crates/tui/tests/all/more_tools.rs @@ -256,6 +256,28 @@ fn a_subagent_row_opens_its_child_session() { assert!(support::lines(&h.log).iter().any(|line| line == "GET /api/session/ses_child/message"),); } +#[test] +fn a_background_subagent_row_follows_its_child_status() { + let messages = turn(vec![tool( + "c1", + "task", + completed( + json!({ "description": "Check the docs", "agent": "general" }), + "done", + json!({ "sessionID": "ses_child", "status": "running" }), + ), + )]); + let h = open(100, 30, messages); + h.wait_for(" ✓ General Subagent — Check the docs Background\n"); + let child = support::merge(session("ses_child", "Child work"), json!({ "parentID": "ses_t" })); + h.tui.data.remember(serde_json::from_value(child).unwrap()); + let child = SessionID("ses_child".into()); + h.tui.data.set_status(&child, opencode_store::SessionStatus::Running); + h.wait_for(" ⋯ General Subagent — Check the docs Background\n"); + h.tui.data.set_status(&child, opencode_store::SessionStatus::Idle); + h.wait_for(" ✓ General Subagent — Check the docs Background\n"); +} + #[test] fn execute_lists_its_calls_and_opens_the_dialog() { let calls = json!([